我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?
谢谢。
编辑:
感谢您的回答。我现在明白了盐的主要(也许只是?)目的是使彩虹表的生成变得不可能 - 你不能预先生成“P@$$w0rd”的散列,因为它对于每个可能都有不同的散列盐值。我完全理解这一点,但是......这真的与对称加密有关吗?我没有将哈希存储在任何地方吗?因此,即使攻击者拥有所有可能的密码组合的彩虹表,他也无能为力,对吧?
所以,我现在的问题是:在与对称加密算法(如 .NET 的 AesManaged)一起使用时,与使用密码派生(甚至硬编码)盐相比,在每个加密操作中使用随机盐有什么优势吗?