Cryptography gurus please help.
I’ve learned that encryption key with symmetric algorithms (e.g. AES) should be derived from password via the PBKDF2 function, using the random salt in each encryption. I’ve also learned that IV should not be hard-coded, or directly bound to (derived from) password string or encryption key. Until now I was generating both key derivation salt and IV randomly, 16 bytes each for my AES-256 encryption, and storing them along with encrypted payload.
Now I’m thinking random-generation of IV is redundant, if I use random salt, as I can derive both key and IV from password string with that salt. Or maybe I shouldn’t?
So my question is ultimately this:
Can I derive initialization vector from password (as I do with key), or should I generate random IV each time, given the fact that I use random salt in each encryption?
So can I use the below C# code?
// Derive key and initialization vector from password:
// ---> NOTE: _salt is random 16 bytes in each encryption.
byte[] key, iv;
using (Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(password, _salt, _iterations))
{
key = derivedBytes.GetBytes(32);
iv = derivedBytes.GetBytes(16);
}
Yes you can use it that way, as long as you never ever use the same salt for the same password (even in time) to calculate the key and IV. The IV only has to be unique when you encrypt with the same key, and you would calculate a new key each time. In principle you could even use an all zero IV, as the key is never repeated, but you are better off using a derived one.
Note that if one of your colleagues decides that
PasswordDeriveBytes– the broken implementation of PBKDF1 from Microsoft – would be better suited for the task, then you may very well be vulnerable to all kinds of attacks. This is just an example what can go wrong if your security margins are tight…Fully random IV’s should certainly be preferred.