【发布时间】:2012-09-21 11:25:54
【问题描述】:
我正在使用 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)?
【问题讨论】:
-
最好只存储密码的哈希值。与加密密码相比,即使攻击者控制您的代码并知道密钥,哈希值也无法反转。那么为什么要加密密码(PBKDF2 不是加密,它是散列)?
-
@martinstoeckli,我没有加密密码,也没有将其哈希存储在任何地方。我只是从字符串密码中导出加密密钥(和 iv),然后用它加密有效负载。
-
我想我现在明白了。您想先从密码计算哈希值,然后使用此哈希值加密某些数据(而不是直接使用原始密码)。
标签: c# .net security encryption cryptography