Reputation: 2028
I'm trying to decompress a stream, using a GZipStream and BinaryStream, but I'm failing.
Can you help me?
public static LicenseOwnerRoot GetLicenseFromStream(Stream stream)
{
using (BinaryReader br = new BinaryReader(stream))
{
string keyCrypto = br.ReadString();
string xmlCrypto = br.ReadString();
string key = Cryptography.Decrypt(keyCrypto);
string xml = Cryptography.Decrypt(key, xmlCrypto);
byte[] data = Encoding.UTF8.GetBytes(xml.ToCharArray());
using (MemoryStream ms = new MemoryStream(data))
{
using (GZipStream decompress = new GZipStream(ms, CompressionMode.Decompress))
{
xml = Encoding.UTF8.GetString(data);
LicenseOwnerRoot root = (LicenseOwnerRoot)Utility.XmlDeserialization(typeof(LicenseOwnerRoot), xml);
foreach (LicenseOwnerItem loi in root.Licenses)
loi.Root = root;
return root;
}
}
}
}
That xml is compressed and encrypted, so I have to decompress and then decrypt. When I try to read, throws one expections with this message: The magic number in GZip header is not correct. I tried so many times to fix that, but It's sounds workable. The question is: how I should use the 'usings' and if that way is right, or exists another way to do what I'm trying to do? I have to decompress before to use BinaryReader?
Actually, I have to do the inverse of this method:
public static void GenerateLicenseStream(string key, LicenseOwnerRoot root, Stream stream)
{
using (BinaryWriter sw = new BinaryWriter(stream))
{
string xml = Utility.XmlSerialization(root);
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream compress = new GZipStream(ms, CompressionMode.Compress))
{
byte[] data = Encoding.UTF8.GetBytes(xml.ToCharArray());
compress.Write(data, 0, data.Length);
string keyCrypto = Cryptography.Encrypt(key);
string xmlCrypto = Cryptography.Encrypt(key, Encoding.UTF8.GetString(ms.ToArray()));
sw.Write(keyCrypto);
sw.Write(xmlCrypto);
}
}
}
}
Upvotes: 4
Views: 3441
Reputation: 10380
I wrote up a quick sample for you, it doesnt do the encryption but it highlights where encryption / decryption should occur. This is the content of a .NET Console app that you can run "as is":
static void Main(string[] args)
{
var content = @"someTextOrXMLContentGoesHereCanBeAnything#$&%&*(@#$^";
var data = Encoding.UTF8.GetBytes(content.ToCharArray());
var fs = new StreamWriter(@"c:\users\stackoverflow\desktop\sample.bin");
using (var bw = new BinaryWriter(fs.BaseStream))
{
using (var ms = new MemoryStream())
{
using (var compress = new GZipStream(ms, CompressionMode.Compress, true))
{
compress.Write(data, 0, data.Length);
}
// encrypt goes here
var compressedData = ms.ToArray();
Console.WriteLine(compressedData.Length); // 179
bw.Write(compressedData);
}
}
// and the reverse...
using (var fs2 = new StreamReader(@"c:\users\stackoverflow\desktop\sample.bin"))
{
using (var br = new BinaryReader(fs2.BaseStream))
{
var len = (int)br.BaseStream.Length;
var encrypted = br.ReadBytes(len);
// decrypt here
var decrypted = encrypted; // <== new result after decryption
using (var ms = new MemoryStream(decrypted))
{
List<byte> bytesList = new List<byte>();
using (var decompress = new GZipStream(ms, CompressionMode.Decompress, true))
{
int val = decompress.ReadByte();
while (val > -1)
{
bytesList.Add((byte)val);
val = decompress.ReadByte();
}
}
var final_result = new String(Encoding.UTF8.GetChars(bytesList.ToArray()));
Console.WriteLine(final_result);
}
}
}
Console.ReadLine();
}
Upvotes: 2
Reputation: 22673
You are treating compressed data as a utf-8 byte array. Utf-8 actually has very strict rules so half of your compressed data is probably getting replaced by question marks (placeholders for an invalid character) in that step.
You need to encrypt/decrypt the raw binary data, and lose the string conversion. Compressed data is not a string and shouldn't be treated as such.
If your encryption method can only operate on strings (I don't have the definition of your Cryptography
class), then you have no choice but to encrypt the XML data first and then compress it (though it will probably not compress as well that way).
You are also not actually doing any decompression; you construct a MemoryStream
and GZipStream
for the compressed data, but then don't do anything with them and try to use data
directly.
Upvotes: 2
Reputation: 100527
You are not reading anything from "decompress". You need to read all data from the "decompress" (since there is no length of the data stored you have to read till stream is empty) and than convert it to string as you are doing.
Upvotes: 2