I need to encrypt a large contiguous amount of bytes, not fitting into single byte array.
There are already a few similar questions, but none of the answers works for me:
stackoverflow.com/questions/5090233/how-to-encrpyt-decrypt-data-in-chunks stackoverflow.com/questions/45735983/encrypting-files-with-aes-c-sharp-in-chunks stackoverflow.com/questions/27645527/aes-encryption-on-large-files
Following code works if the output length is under limit (Key and IV are hardcoded for testing):
byte[] encrypt(byte[] input, byte[] iv = null)
{
var aes = new AesManaged();
aes.KeySize = 128;
aes.Key = new byte[16] { 0x0F, 0xD4, 0x33, 0x82, 0xF4, 0xDF,
0x62, 0xA5, 0x55, 0x7C, 0x6E, 0x92, 0xC5, 0x64, 0x67, 0xA9 };
aes.IV = (iv != null) ? iv :
new byte[16] { 0xB3, 0x87, 0xDA, 0xA0, 0x47, 0x7C,
0x52, 0x76, 0xCB, 0x3A, 0x69, 0x9B, 0x0F, 0x82, 0xAF, 0xA7 };
using (var stream = new MemoryStream()) // size limit is 2 GB
using (var cryptoStream = new CryptoStream(stream,
aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(input, 0, input.Length);
cryptoStream.FlushFinalBlock();
return stream.ToArray(); // max number of bytes = int.MaxValue
}
}
One alternative is to use FileStream instead of MemoryStream, but I prefer to get the results in memory.
I am trying to implement the chain operation, dividing the input on chunks of [multiples of AES BlockSize] and capture the encrypted output after feeding each chunk.
According to what I read, the last bytes of each result are supposed to be used as an IV for the next encryption, but that does not work. For simplicity, chunk size is equal to BlockSize:
byte[] subArray(byte[] source, int start, int length = -1)
{
if (length == -1) length = source.Length - start;
var target = new byte[length];
Buffer.BlockCopy(source, start, target, 0, length);
return target;
}
var encr0 = encrypt(subArray(input, 0, blockSize * 2));
var encr1 = encrypt(subArray(input, 0, blockSize));
var encr2 = encrypt(subArray(input, blockSize, blockSize),
subArray(encr1, blockSize, 16));
Assert.IsTrue(encr2.SequenceEqual(subArray(encr0, blockSize))); // FAILS
What I am doing wrong?