1

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
}
Daniel Corzo
  • 1,055
  • 2
  • 19
  • 32
drowhunter
  • 371
  • 2
  • 12

1 Answers1

1

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
        }; 
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • I guess by definition it's not a bug.. but I still feel like it's a strange implementation. without reflecting you would never expect that to happen. it goes against the rules of object initialization. plus it just feels dirty to have one property secretly nullify another. – drowhunter Dec 04 '16 at 04:22
  • since those properties are `public virtual` you can make your own class, inherit from `RijndaelManaged` and override `Key` and `KeySize` . But I would first look for reason why its implemented this way. perhaps having different `KeySizeValue` from `KeyValue` introduces some other bugs or even run time errors etc. @drowhunter – M.kazem Akhgary Dec 04 '16 at 08:56
  • 1
    yes makes sense but it begs the question ..if if the key array and keysize need to match why even allow them to be set differently at all? seems like poor logic to me. – drowhunter Dec 04 '16 at 16:26