我使用KeyDerivation.Pbkdf2生成密码哈希,我想知道关于盐长度的一般建议与Pbkdf2输出的总哈希长度相比是什么。
在下面的实现中,我使用HMACSHA512,并假设salt是512位,而hashBitLength也是512位。
KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA512, iterationCount, hashBitLength / 8);
我看过一个使用HMACSHA256的示例,但它的salt设置为128位,总哈希位长度为256。 为什么采取这种方法?
我已经读到512位可能有点过分,但就存储而言,它并不关心我(我不确定性能如何受到影响,我还没有测量了)。
盐的长度是否与整个结果哈希的长度相同。 它应该是一半吗? 或者是否应该超过某个阈值且低于总长度?
我的直觉说我做的方式是正确的(除了512位之外)因为我怀疑我获得了最大的熵,但我没有加密技师。
有人可以帮我澄清一下吗?
答案 0 :(得分:3)
它真的不需要那么大,但让我们理解为什么。盐的目的是:
第一点可以通过简单地使用计数器来实现 - 至少可以防止来自您自己的数据库的重复,但它可能无法防止数据库中的密码哈希与相同密码的哈希相同在别人的数据库中。这将我们带到第二点。
如果只使用从零开始的计数器,则可以基于它构建彩虹表。盐越大,彩虹桌就越有可能有效。这些表随着盐的大小呈指数增长,所以你的盐真的不必那么大来排除这种攻击。
很难指出确切的最小尺寸,但我可以向你保证128位是绰绰有余的。我个人,作为一名安全代码审核员,肯定不会提出一个只有64位的问题。
关于这个主题的安全建议的一个大问题是没有人分析它 - 而是你只是得到自称是专家的人的盲目推荐。我在password processing上撰写了一篇论文,正是提出了这一点。有关盐的咆哮,请参阅第3节。
备注:完全排除彩虹表,不要使用计数器。相反,选择你的盐'足够大'(如上所述)并以不可预测的方式。