I'm using Rfc2898DeriveBytes
to securely generate encryption key and initialization vector from user-supplied string password, to use with symmetric encryption (e.g. AesManaged).
I'm taking the SHA1 hash of password as a salt parameter to Rfc2898DeriveBytes
. Is that ok? If not, then where should I get the salt from? I will need the same salt when decrypting, right? So I have to store it somewhere unencrypted - unsecured. If I have to store it securely, then it just becomes another "password", isn't it?
void SecureDeriveKeyAndIvFromPassword(string password, int iterations,
int keySize, int ivSize, out byte[] key, out byte[] iv)
{
// Generate the salt from password:
byte[] salt = (new SHA1Managed()).ComputeHash(Encoding.UTF8.GetBytes(password));
// Derive key and IV bytes from password:
Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(password, salt, iterations);
key = derivedBytes.GetBytes(keySize);
iv = derivedBytes.GetBytes(ivSize);
}
I've seen using the constant (hard-coded) salt, and I've seen people complaining about it. I thought deriving salt from password would be the better idea, but I'm not sure this is an optimal solution.
Shortly, I have a file that needs to be encrypted, and password string input by user. How do I properly use Rfc2898DeriveBytes
to derive secure encryption key and IV?
Thanks.
EDIT:
Thanks for your answers. I now understand that the main (maybe only?) purpose of salt is to make generation of rainbow tables impossible - you can't pre-generate the hash of "P@$$w0rd" because it will have a different hash for each possible salt value. I understand this perfectly, BUT... Is this really relevant to symmetric encryption? I'm not storing the hash anywhere right? So even if the attacker has the rainbow table for all possible password combinations, he can't do much, right?
So, my question now is: Is there any advantage of using the random salt in each encryption operation, compared to using password-derived (or even hard-coded) salt, when used with symmetric encryption algorithms (like AesManaged of .NET)?