private const int KEY_SIZE = 128;
private const int BLOCK_SIZE = KEY_SIZE / 8;
public static byte[] AES_CTR(byte[] key, byte[] counter, byte[] data)
{
byte[] result = data;
byte[] block = counter, encBlock = new byte[BLOCK_SIZE];
int blocklength = data.Length / BLOCK_SIZE;
RijndaelManaged rm = new RijndaelManaged();
rm.Mode = CipherMode.ECB;
rm.Padding = PaddingMode.None;
rm.KeySize = KEY_SIZE;
rm.BlockSize = KEY_SIZE;
rm.Key = key;
rm.IV = new byte[0x10]; //iv is not needed in ECB mode
using (ICryptoTransform ict = rm.CreateEncryptor())
{
for (int i = 0; i < blocklength; i++)
{
//increase counter block id, note: we only use 4 byte, thats more then enough to encrypt up to 68 GB...
Array.Copy(BitConverter.GetBytes(i), 0, block, BLOCK_SIZE - 4, 4);
Array.Reverse(block, BLOCK_SIZE - 4, 4);
//encrypt counter
ict.TransformBlock(block, 0, BLOCK_SIZE, encBlock, 0);
//de/encrypt data
XorBlock(result, i * BLOCK_SIZE, encBlock);
}
}
rm.Clear();
return result;
}
public static void XorBlock(byte[] dst, int offset, byte[] xorBlock)
{
for (int i = 0; i < xorBlock.Length; i++)
dst[i + offset] ^= xorBlock[i];
}