7

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)一起使用时,与使用密码派生(甚至硬编码)盐相比,在每个加密操作中使用随机盐有什么优势吗?

4

5 回答 5

9

每个密码的盐应该是唯一的,这意味着为您要散列的每个密码创建一个随机密码。盐不是秘密,可以使用您计算的哈希值存储纯文本。

盐的想法是,攻击者不能使用预建的彩虹表来获取密码。他必须为每个密码分别建立这样一个彩虹表,这没有意义。在找到匹配之前,暴力破解更容易。

MSDN中有一个示例,其中盐是从操作系统的随机源中获取的。这是你能做的最好的事情,为了获得安全的盐,不要从你的密码中得到它。

于 2012-09-21T11:58:23.583 回答
4

salt旨在通过使每个目标的行为不同来防止多目标攻击。彩虹表只是多目标攻击的一种特殊形式,在获得目标之前就已经花费了计算量。

在某些情况下,多目标攻击适用,但彩虹表不适用。

这方面的一个例子:假设您正在使用具有语义安全性的经过身份验证的加密方案,例如具有唯一随机数的 AES-GCM。现在您已经获得了一百万条使用不同密码加密的不同消息。

如果不使用 salt,要检查密码是否适用于其中任何一项,攻击者需要进行一次 KDF操作和一百万次解密操作。如果使用盐,攻击者需要一百万次 KDF操作和一百万次解密操作。由于与解密相比,KDF 速度较慢,因此对第一种方案的攻击比对第二种方案的攻击要快得多。

于 2012-09-21T13:57:52.770 回答
3

我真的不知道是什么,Rfc2898DeriveBytes但我可以告诉你以下内容:盐不一定是安全的。现在,您说您已经看到人们抱怨盐的硬编码、恒定值,以及谁说的都是对的。盐应该是一个随机值,而不是一个恒定值,否则它的目的就失败了。

你了解盐的用途吗?你显然没有。使用散列作为盐是一个坏主意,因为密码X将始终使用相同的值Y加盐,这再次违背了它的目的。

于 2012-09-21T11:50:44.967 回答
3

人们不喜欢硬编码的盐,因为项目的所有开发人员都可以访问它们(在开源项目或逆向工程的情况下可能是公众)。然后,攻击者可以为您的特定盐计算彩虹表并开始攻击您的系统。

盐值的一个很好的选择是:

  • 每次检查密码时都可用
  • 在密码检查之间不改变
  • 每个(或大多数)密码计算不同

如果用户名不能更改,那么用户名将是一个不错的选择。或者,在您第一次创建用户并将其存储为 salt 时生成一个完全随机的值,以及数据库中的用户数据。

于 2012-09-21T11:52:52.463 回答
0

其他人已经解释了盐的用途,以及为什么它可以成为公共信息。

您的问题的另一部分答案是:不要从密码本身中提取盐。这与在 Ashley Madison 黑客攻击后最终暴露数百万个密码的编程错误非常相似。

问题是,当您使用密码生成盐时,您实际上是在瞬间使密码可用,而且更容易破解。攻击者可以完全忽略 PBKDF2 的输出,并简单地反转 salt 本身。这仅受 SHA1 保护,该 SHA1 已经损坏。

在阿什利麦迪逊,错误是相似的。密码使用 bcrypt 存储在主数据库中,并且被认为是安全的。但后来有人发现,很多账户的密码实际上被存储了两次,而第二个副本只使用了 MD5 保护。

于 2015-10-26T09:19:14.170 回答