Search code examples
c#rijndaelmanaged

Strange behaviour during RijndaelManaged construction


I've noticed the following strange behaviour in the following code, if I set the Key in an object initializer it generates a random key and doesn't set my key. Is this a glitch?

var algorithm = new RijndaelManaged
{
    Mode = CipherMode.CBC,
    Key = keyBytes,        //if i set the keyBytes here
    KeySize = _keySize,
    IV = Encoding.ASCII.GetBytes(_initVector),
    BlockSize = 128,
    Padding = PaddingMode.Zeros
}; // Set encryption mode to Cipher Block Chaining   

bool wtf= algorithm.Key.AreEqual(keyBytes);

if (!wtf) // <!-- the Key is not the same here
{
    algorithm.Key = keyBytes; // so i end up having to set it again here so that i can decrypt properly
}

Solution

  • Its not bug. Look at source code

    This is Key property.

        public virtual byte[] Key {
            get { 
                if (KeyValue == null) GenerateKey();
                return (byte[]) KeyValue.Clone();
            }
            set { 
                if (value == null) throw new ArgumentNullException("value");
                Contract.EndContractBlock();
                if (!ValidKeySize(value.Length * 8))
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
    
                // must convert bytes to bits
                KeyValue = (byte[]) value.Clone(); // your byte[] will be set
                KeySizeValue = value.Length * 8;   // key size will be set too
            }
        }
    

    This is KeySize property.

    public virtual int KeySize {
        get { return KeySizeValue; }
        set {
            if (!ValidKeySize(value))
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
    
            KeySizeValue = value;
            KeyValue = null; // here keyvalue becomes null
        }
    }
    

    That's because you set KeySize after setting KeyValue therefore the problem you get.

    I think you should not setKeySize because it will be set automatically as you can see in source code. if you set KeySize your Key becomes null by implementation for what ever reason.

    var algorithm = new RijndaelManaged
            {
                Mode = CipherMode.CBC,
                Key = keyBytes,
                // KeySize = _keySize, // remove this
                IV = Encoding.ASCII.GetBytes(_initVector),
                BlockSize = 128,
                Padding = PaddingMode.Zeros
            };