Search code examples
c#aes

What is the purpose of key and IV assignment to AES object?


In MSDN for AES I can see the following part in the sample.

...
using (Aes aesAlg = Aes.Create())
{
  aesAlg.Key = Key;
  aesAlg.IV = IV;
  ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
  ...
} ...

I've tried to skipping the assignment of key and IV to the AES object (although setting them in the creation of the encryptor like this.

...
using (Aes aesAlg = Aes.Create())
{
  //aesAlg.Key = Key;
  //aesAlg.IV = IV;
  ICryptoTransform encryptor = aesAlg.CreateEncryptor(Key, IV);
  ...
} ...

It seems to make no difference in the outcome. However, since it is a part of the sample, I worry that there is a case when it matters. It might be that I only tried examples where it doesn't show.

When do I need to assign the key and IV to the AES object?


Solution

  • In the first code snippet, you've assigned values to the Key and IV properties of the symmetric algorithm object so you don't need to pass them again when you create the crypto transform. In this case, use the parameterless overload which uses the already assigned Key and IV to create the encryptor/decryptor.

    using (Aes aesAlg = Aes.Create())
    {
      aesAlg.Key = Key;
      aesAlg.IV = IV;
      ICryptoTransform encryptor = aesAlg.CreateEncryptor();
      // ...
    }
    

    The second code snippet will create the same transform using the passed Key and IV params regardless of the aesAlg.Key and aesAlg.IV values. Consider the following:

    using (Aes aesAlg = Aes.Create())
    {
      aesAlg.Key = Key;
      aesAlg.IV = IV;
      ICryptoTransform encryptor = aesAlg.CreateEncryptor(someOtherKey, somOtherIV);
      // ...
    }
    

    Here, someOtherKey and someOtherIV are used to create the transform and the aesAlg properties are ignored. Another example to consider:

    using (Aes aesAlg = Aes.Create())
    {
      ICryptoTransform encryptor = aesAlg.CreateEncryptor();
      // ...
    }
    

    Now, both aesAlg.Key & aesAlg.IV properties are null and the .CreateEncryptor() will use them to create the transform. However, the method won't throw any exceptions because the getters of these properties - by design - don't return null and they create and assign random values instead.

    You might want to try the following:

    private void SomeCaller()
    {
        using (var crypto = Aes.Create())
        {
            // A random Key is generated...
            PrintHexValue(crypto.Key);
            // And assigned...
            PrintHexValue(crypto.Key);
    
            var pass = "Konrad Viltersten";
            var bytes = Encoding.UTF8.GetBytes(pass);
            var rfc = new Rfc2898DeriveBytes(pass, 
                new SHA256Managed().ComputeHash(bytes), 1000);
            var key = rfc.GetBytes(crypto.LegalKeySizes[0].MaxSize / 8);
            var iv = rfc.GetBytes(crypto.LegalBlockSizes[0].MinSize / 8);
    
            // Doesn't change the crypto.Key and crypto.IV properties...
            var encr = crypto.CreateEncryptor(key, iv);
    
            // The generated password-based key...
            PrintHexValue(key);
            // The random key remains...
            PrintHexValue(crypto.Key);
    
            crypto.Key = key;
            crypto.IV = iv;
    
            // The password-based key is assigned to the crypto.Key...
            PrintHexValue(crypto.Key);
        }
    }
    
    private void PrintHexValue(byte[] bytes) =>
        Console.WriteLine(BitConverter.ToString(bytes).Replace("-", string.Empty));
    

    Conclusion

    Your second code snippet is a shortcut to create a crypto transform. You'll need the first one In wider scopes like this one for example.