public static byte[] SymmetricEncrypt( byte[] input, byte[] key )
{
Debug.Assert( key.Length == 32 );
using ( var aes = new RijndaelManaged() )
{
aes.BlockSize = 128;
aes.KeySize = 256;
// generate iv
byte[] iv = GenerateRandomBlock( 16 );
byte[] cryptedIv = new byte[ 16 ];
// encrypt iv using ECB and provided key
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
using ( var aesTransform = aes.CreateEncryptor( key, null ) )
{
cryptedIv = aesTransform.TransformFinalBlock( iv, 0, iv.Length );
}
// encrypt input plaintext with CBC using the generated (plaintext) IV and the provided key
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using ( var aesTransform = aes.CreateEncryptor( key, iv ) )
using ( var ms = new MemoryStream() )
using ( var cs = new CryptoStream( ms, aesTransform, CryptoStreamMode.Write ) )
{
cs.Write( input, 0, input.Length );
cs.FlushFinalBlock();
byte[] cipherText = ms.ToArray();
// final output is 16 byte ecb crypted IV + cbc crypted plaintext
byte[] output = new byte[ cryptedIv.Length + cipherText.Length ];
Array.Copy( cryptedIv, 0, output, 0, cryptedIv.Length );
Array.Copy( cipherText, 0, output, cryptedIv.Length, cipherText.Length );
return output;
}
}
}