C# 盐长度与总散列长度之比

C# 盐长度与总散列长度之比,c#,security,hash,passwords,pbkdf2,C#,Security,Hash,Passwords,Pbkdf2,我使用keydrivation.Pbkdf2生成密码散列,我想知道与Pbkdf2输出的总散列长度相比,salt长度的一般建议是什么 在下面的实现中,我使用HMACSHA512,并假设salt是512位,hashBitLength也是512位 KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA512, iterationCount, hashBitLength / 8); 我见过一个使用HMACSHA256的示例,但是它将s

我使用keydrivation.Pbkdf2生成密码散列,我想知道与Pbkdf2输出的总散列长度相比,salt长度的一般建议是什么

在下面的实现中,我使用HMACSHA512,并假设salt是512位,hashBitLength也是512位

KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA512, iterationCount, hashBitLength / 8);
我见过一个使用HMACSHA256的示例,但是它将salt设置为128位,而总哈希位长度设置为256位。 为什么要采取这种做法

我曾读到512位可能是多余的,但就存储而言,这与我无关(但我不确定性能会受到什么影响,我还没有测量到这一点)

盐的长度应该与产生的整个散列长度相同。 应该是一半吗? 或者应该是高于某个阈值、低于总长度的任何值

我的直觉告诉我这样做是正确的(除了512位之外),因为我怀疑我得到了最大熵,但我不是密码学家


有人能帮我澄清一下吗?

它真的不需要那么大,但让我们理解为什么。盐的用途是:

  • 如果两个人拥有相同的密码,“哈希”结果不应该相同
  • 阻止
  • 第一点可以通过简单地使用计数器来实现——至少可以防止您自己的数据库中出现重复的密码,但它可能不会防止您数据库中的密码哈希与其他人数据库中相同密码的哈希相同。这就引出了第二点

    如果一个人仅仅使用一个从零开始的计数器,那么他就可以基于它构建一个彩虹表。盐越大,彩虹桌就越大,才有可能发挥作用。这些表随着盐的大小呈指数增长,所以你的盐真的不必那么大就可以排除这种攻击

    很难精确指出最小大小,但我可以向您保证128位就足够了。作为一名安全代码审计员,我个人肯定不会提出一个只有64位的salt问题

    关于这个话题的安全建议的一个大问题是,从来没有人对它进行过分析——相反,你只能从自称是专家的人那里得到盲目的建议。我写了一篇论文来阐述这一点。具体参见第3节,了解我对盐的咆哮


    备注:为了完全排除彩虹桌,不要使用计数器。取而代之的是,选择“足够大”(如上所述)且不可预测的盐。

    感谢你的文章链接,里面有很多值得阅读的内容。还有一些问题我还需要回答:1)盐的长度应该和散列的长度一样吗?i、 e.如果我使用HMAC512,盐应该是512位吗?我看到一些消息来源说salt和散列算法是不相关的,其他人说它们应该是相同的长度。2) 更长的盐不会使攻击在计算上更昂贵吗?或者仅仅是唯一性才算数,而不是盐长度(例如,256位的盐和4096位的盐一样安全?@Steviebob:1)不,盐长度和哈希之间没有关系。事实上,昨天刚刚发现NIST现在说盐只需要32位——见。那些声称其长度必须与散列长度相同的人不知道他们在谈论什么,因为他们缺乏对该声明的正当性。2) 盐并没有使任何东西在计算上更昂贵。它用于唯一性,防止重复输出和彩虹攻击。