Reputation: 89
I am obviously doing something wrong here, but I don't understand why this is happening. I have been experianceing bugs in my encrypt stream function and added additional code to display to Visual studio's debugger what is going on in the function. To my discovery, the encrypted version of what ever data I send into it is shorter than the original stream, and attempts to decrypt the stream results in an even shorter stream.
public Stream encryptStream(Stream input)
{
MemoryStream output = new MemoryStream();
RijndaelManaged alg = new RijndaelManaged();
alg.Padding = PaddingMode.PKCS7;
byte[] key = HashStringMD5(DefaultKey);
alg.KeySize = key.Length * 8;
alg.Key = key;
alg.IV = key;
CryptoStream crypt = new CryptoStream(output, alg.CreateEncryptor(), CryptoStreamMode.Write);
output.Position = 0;
input.CopyTo(crypt);
byte[] EncryptedCopy = output.ToArray();
byte[] InputCopy = new byte[input.Length];
input.Position = 0;
input.Read(InputCopy, 0, InputCopy.Length);
output.Position = 0;
MemoryStream test = new MemoryStream();
crypt.Close();
crypt = new CryptoStream(test, alg.CreateDecryptor(), CryptoStreamMode.Write);
crypt.Write(EncryptedCopy, 0, EncryptedCopy.Length);
test.Position = 0;
byte[] DecryptionTest = test.ToArray();
input.Position = 0;
return output;
}
not sure what is causing the data loss as shown below
Upvotes: 1
Views: 145
Reputation: 20157
You just need to flush to the containing stream at the right time. Also, you have quite a few resources which implement IDisposable
and are disposed of most easily by employing the using
construct. This should produce the results you are looking for as well as properly deterministically disposing of resources:
public Stream encryptStream(Stream input)
{
var output = new MemoryStream();
using (var alg = new RijndaelManaged { Padding = PaddingMode.PKCS7 })
{
var key = HashStringMD5(DefaultKey);
alg.KeySize = key.Length * 8;
alg.Key = key;
alg.IV = key;
byte[] encryptedCopy;
using (var enc = alg.CreateEncryptor())
{
var crypt = new CryptoStream(output, enc, CryptoStreamMode.Write);
input.CopyTo(crypt);
crypt.FlushFinalBlock();
encryptedCopy = output.ToArray();
}
var inputCopy = new byte[input.Length];
input.Position = 0;
input.Read(inputCopy, 0, inputCopy.Length);
using (var test = new MemoryStream())
using (var dec = alg.CreateDecryptor())
using (var crypt = new CryptoStream(test, dec, CryptoStreamMode.Write))
{
crypt.Write(encryptedCopy, 0, encryptedCopy.Length);
crypt.FlushFinalBlock();
var decryptionTest = test.ToArray();
if (decryptionTest.Length != inputCopy.Length || decryptionTest.Where((t, i) => t != inputCopy[i]).Any())
{
throw new InvalidOperationException("not orthogonal");
}
}
}
input.Position = 0;
output.Position = 0;
return output;
}
Though I might split the testing code into a separate method as it adds noise to the simplicity of the encrypting code.
Upvotes: 2