Search code examples
c#rijndaelmanaged

RijndaelManaged - What does setting KeySize property do?


Given I am setting the KeySize to be 192, when I am encrypting some data by doing the following:

 static void Main()
        {
            var querystrings = "dataToEncrypt";
            byte[] keyvalue = new byte[] { 241, 205, 121, 123, 109, 246, 247, 103, 31, 225, 167, 220, 247, 119, 247, 119, 78, 125, 127, 167, 156, 213, 230, 250, };
            byte[] ivvalue = new byte[] { 194, 177, 79, 213, 87, 46, 213, 189, 243, 169, 32, 13, 217, 62, 34, 170, };
            byte[] querystringBytes = Encoding.UTF8.GetBytes(querystrings);

            using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
            {
                rijndaelManaged.BlockSize = 128;
                rijndaelManaged.KeySize = 192;
                rijndaelManaged.IV = ivvalue;
                rijndaelManaged.Key = keyvalue;
                rijndaelManaged.Padding = PaddingMode.PKCS7;
                rijndaelManaged.Mode = CipherMode.CBC;

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    ICryptoTransform transform = rijndaelManaged.CreateEncryptor();
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(querystringBytes, 0, querystringBytes.Length);
                        cryptoStream.FlushFinalBlock();
                        var output = Convert.ToBase64String(memoryStream.ToArray());
                        Console.WriteLine($"{output}");
                        Console.ReadKey();
                    }
                }
            }
        }

The data encrypts as I'd expect as the IV and encryption key are 128 bits and 192 bits long respectively. If however I set the encryption key to be 128 bits long (for arguments sake, lets use the same byte array as the IV) i.e.

 static void Main()
        {
            var querystrings = "dataToEncrypt";
            byte[] keyvalue = new byte[] { 194, 177, 79, 213, 87, 46, 213, 189, 243, 169, 32, 13, 217, 62, 34, 170, };
            byte[] ivvalue = new byte[] { 194, 177, 79, 213, 87, 46, 213, 189, 243, 169, 32, 13, 217, 62, 34, 170, };
            byte[] querystringBytes = Encoding.UTF8.GetBytes(querystrings);

            using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
            {
                rijndaelManaged.BlockSize = 128;
                rijndaelManaged.KeySize = 192;
                rijndaelManaged.IV = ivvalue;
                rijndaelManaged.Key = keyvalue;
                rijndaelManaged.Padding = PaddingMode.PKCS7;
                rijndaelManaged.Mode = CipherMode.CBC;

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    ICryptoTransform transform = rijndaelManaged.CreateEncryptor();
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(querystringBytes, 0, querystringBytes.Length);
                        cryptoStream.FlushFinalBlock();
                        var output = Convert.ToBase64String(memoryStream.ToArray());
                        Console.WriteLine($"{output}");
                        Console.ReadKey();
                    }
                }
            }
        }

This will still encrypt without exception. My question is:

What does the KeySize do internally as it's accepting a 128 bit encryption key when I am explicitly setting the KeySize as 192? Why is no exception occurring?


Solution

  • The Key and KeySize properties of the RijndaelManaged class are inherited from the base SymmetricAlgorithm class. The precise behavior of these properties isn't well documented in MSDN Library, but if you look at the SymmetricAlgorithm source code, you'll see that the Key and KeySize properties interact with each other as follows:

    • When you set the Key property, the KeySize property is automatically set to the length of the new key in bits.
    • When you set the KeySize property, the existing Key is cleared out (and a new random key is automatically generated the next time Key is accessed).

    Therefore, if you're setting the Key property, there's no point in setting the KeySize property beforehand.