c# - 从密码字符串派生加密 key 和 IV 时,可以使用密码的 SHA1 散列作为盐吗?

标签 c# .net security encryption cryptography

我正在使用 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/

相关文章:

c# - Excels 的等效 C# 函数 Norm.S.Inv 函数

c# - 捕获全局异常是处理重新连接的好方法吗?

.net - 混淆器和技术支持

c# - Internet Explorer 工具栏的上下文菜单

.net - 有谁知道为什么标准框架引用上可能会出现 "manifest definition does not match the assembly reference"错误?

c# - 您如何在 ClickOnce 部署中包含许多其他文件?

c# - UWP - XDocument 等效于 XMLNodeList

c# - 在运行时授予管理员权限

Azure Web App 仅通过应用程序网关并禁用直接访问

java - 将 Java 应用程序锁定到特定 PC