Search code examples
c#encryption.net-coreaesencryption-symmetric

How to symmetrically encrypt & decrypt some data in C# using AES?


I'm trying to encrypt & decrypt some data using AES. But i'm only getting garbled output. What am I doing wrong?

static void Test()
{
    byte[] myFileBytes; // Will contain encrypted data. First the IV, then the ciphertext.
    var myPassword = "helloworld";
    var dataToEncrypt = "this is a test";

    // STEP 1: Encrypt some data:

    byte[] key;

    using (var sha256 = SHA256.Create())
        key = sha256.ComputeHash(Encoding.UTF8.GetBytes(myPassword));

    using (var myFileStream = new MemoryStream())
    using (var aes = System.Security.Cryptography.Aes.Create())
    {
        aes.Key = key;
        myFileStream.Write(aes.IV); // Use the default created by AES, which is presumably non-pseudo random

        using (var cryptoStream = new CryptoStream(myFileStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
        {
            cryptoStream.Write(Encoding.UTF8.GetBytes(dataToEncrypt));
            cryptoStream.Flush();

            myFileBytes = myFileStream.ToArray(); // We are done!

        } // Disposing CryptoStream disposes the underlying MemoryStream
    }

    // STEP 2: Decrypt it to verify that it works

    using (var aes = System.Security.Cryptography.Aes.Create())
    {
        using (var myFileStream = new MemoryStream(myFileBytes))
        {
            var iv = new byte[aes.IV.Length];

            myFileStream.Read(iv, 0, iv.Length);

            using (var cryptoStream = new CryptoStream(myFileStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Read))
            using (var copyStream = new MemoryStream())
            {
                cryptoStream.CopyTo(copyStream);

                var decrypted = Encoding.UTF8.GetString(copyStream.ToArray());

                Debug.Assert(dataToEncrypt == decrypted); // Fails!
            }
        }
    }
}

Solution

  • I would take a look at the example in the documentation and compare to your code.

    Notably when decrypting you are using aes.CreateEncryptor(key, iv). It should probably be aes.CreateDecryptor(key, iv).

    The example from the docs also inputs the key and IV when calling CreateEncryptor, but I'm not sure if that is required or not.

    You should probably not use sha256 to generate the key from a password. The correct way would be a key derivation algorithm. For example Rfc2898DeriveBytes