我正在使用 Rfc2898DeriveBytes
从用户提供的字符串密码中安全地生成加密 key 和初始化向量,以与对称加密(例如 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
来派生安全加密 key 和 IV?
谢谢。
编辑:
感谢您的回答。我现在明白 salt 的主要(也许只是?)目的是使彩虹表的生成变得不可能——你不能预先生成“P@$$w0rd”的散列,因为它对每个可能的散列都有不同的散列盐值。我完全理解这一点,但是......这真的与对称加密相关吗?我没有将哈希存储在任何地方,对吗?因此,即使攻击者拥有所有可能的密码组合的彩虹表,他也无能为力,对吧?
所以,我现在的问题是:与使用密码派生(或什至硬编码)盐相比,在每个加密操作中使用随机盐是否有任何优势,与对称加密算法一起使用时(如 .NET 的 AesManaged)?
最佳答案
盐应该对于每个密码都是唯一的,这意味着为您要散列的每个密码创建一个随 secret 码。盐不是 secret ,可以用您计算的散列值以纯文本形式存储。
salt 的想法是,攻击者无法使用预建的 rainbowtable 来获取密码。他将不得不为每个密码单独构建这样一个彩虹表,这没有意义。在找到匹配项之前,暴力破解更容易。
MSDN中有一个例子其中盐是从操作系统的随机源中获取的。这是你能做的最好的事情,为了获得安全的盐,不要从你的密码中推导出它。
关于c# - 从密码字符串派生加密 key 和 IV 时,可以使用密码的 SHA1 散列作为盐吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12529574/