Click to See Complete Forum and Search --> : CryptoStream To MemoryStream problem


nik88
June 29th, 2009, 02:22 PM
Hi, I am trying to write data to a CryptoStream (which writes an encrypted version of the data to the underlying MemoryStream), then store that data in a byte array.

After that I want to write the data to a MemoryStream and then decrypt that data using a CryptoStream and the underlying MemoryStream that was just written to.

This does not seem to work. I don't get an error, it simply reads Zeros when reading using the CryptoStream.

Here is my code,

public List<byte[]> LoadAsByteArray(IEnumerable<SomeClass> Objects)
{

List<byte[]> ObjectBytes = new List<byte[]>(Objects.Count());

MemoryStream ms = new MemoryStream();
//opens a cryptostream for encryption
Rijndael rijndael = new RijndaelManaged();
rijndael.Padding = PaddingMode.None;
CryptoStream cStream = new CryptoStream(ms, rijndael.CreateEncryptor(Messages.Key, Messages.IV)
, CryptoStreamMode.Write);

foreach (var object in Objects)
{
object.Send(cStream);//writes data using the cryptostream
byte[] data = ms.ToArray();
ObjectsBytes.Add(data);
ms.Seek(0,0);
}

return ObjectsBytes;
}

public List<SomeObject> LoadAsObject(IEnumerable<byte[]> ObjectsBytes)
{

List<SomeObject> Objects = new List<SomeObject>(ObjectsBytes.Count());

//encryption stuff ... using AES encryption
RijndaelManaged rijndael = new RijndaelManaged();
rijndael.Padding = PaddingMode.None;
ICryptoTransform transform = rijndael.CreateDecryptor(Messages.Key, Messages.IV);

MemoryStream ms = new MemoryStream();
//opens the cryptostream
CryptoStream cStream = new CryptoStream(ms, transform,
CryptoStreamMode.Read);
int i = 0;
foreach (var objectbytes in ObjectsBytes)
{
i++;
ms.Write(objectbytes, 0, objectbytes.Length);
ms.Seek(0, 0);
SomeObject object = new SomeObject();
object.Receive(cStream); //reads data from cryptostream
Objects.Add(object);
ms.Seek(0, 0);
}

return Objects;
}


Don't worry about object.send and receive. Think of them as serialize and deserializing the objects to a stream.

Also if I remove the cryptostream and just write and read from the memory stream it works.

If you need more detail on exactly how its behaving I can provide this. Otherwise if you see some problem with the encryption/decription logic let me know.

Thanks in advance,

nik88
June 29th, 2009, 02:37 PM
Update:

So it works when I open a new memorystream and cryptostream within each iteration of the Object List loop.

I would still like to know why the version I posted above doesn't work, since I am working with Lists of 100, 000 items and open two new streams every iteration is a performance hit.

BigEd781
June 29th, 2009, 02:48 PM
Please format your code by surrounding it with [ code][ /code] tags.

boudino
July 1st, 2009, 02:39 AM
I think that it is because you cannot simply reset crypto streams by seeking to begining of the underlying memory stream, because bytes in cryptostream are not independant. As far as I know, byte on position n-1 is part of computation of byte on position n, so I think by spliting the stream to chunks and decrypting each chunk separately as I do it, you lost infromation vital for decryption.

In other words, the solution with opening the streams in each iteration is the only one. Or you could use a single stream for all encrypted object and maintain separated metada which would describe where each object in the stream starts and where ends.