我在用着Rfc2898DeriveBytes
从用户提供的字符串密码安全地生成加密密钥和初始化向量,以与对称加密(例如 AesManaged)一起使用。
我将密码的 SHA1 哈希值作为盐参数Rfc2898DeriveBytes
。这可以吗?如果没有,那么我应该从哪里获取盐?解密时我需要同样的盐,对吧?所以我必须将它存储在未加密的地方 - 不安全的地方。如果我必须安全地存储它,那么它就变成了另一个“密码”,不是吗?
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);
}
我见过使用恒定(硬编码)盐,并且我见过人们抱怨它。我认为从密码中获取盐会是更好的主意,但我不确定这是否是最佳解决方案。
不久,我有一个需要加密的文件,以及用户输入的密码字符串。我该如何正确使用Rfc2898DeriveBytes
导出安全加密密钥和 IV?
Thanks.
EDIT:
感谢您的回答。我现在明白,盐的主要(也许只是?)目的是使彩虹表的生成变得不可能 - 您无法预先生成“P@$$w0rd”的哈希值,因为它对于每种可能都有不同的哈希值盐值。我完全理解这一点,但是......这真的与对称加密相关吗?我没有将哈希值存储在任何地方,对吗?因此,即使攻击者拥有所有可能的密码组合的彩虹表,他也无能为力,对吗?
所以,我现在的问题是:与使用密码派生(甚至硬编码)盐相比,在每个加密操作中使用随机盐是否有任何优势,与对称加密算法一起使用时(如 .NET 的 AesManaged)?