假设我们有统计上长度为 7-8 个字符的密码。由于类似的散列函数输入,附加 200 个字符长的盐是否比 5 个字符的盐更安全?
我想知道:如果有人试图通过暴力破解盐来猜测盐,例如密码“123456”,或者可以在系统中找到的另一个流行密码,甚至是黑客自己帐户的已知密码,该怎么办?
假设我们有统计上长度为 7-8 个字符的密码。由于类似的散列函数输入,附加 200 个字符长的盐是否比 5 个字符的盐更安全?
我想知道:如果有人试图通过暴力破解盐来猜测盐,例如密码“123456”,或者可以在系统中找到的另一个流行密码,甚至是黑客自己帐户的已知密码,该怎么办?
正如 Mike 和 Gumbo 在评论中提到的那样,salt 并不是为了增加对错误密码的保护。这是为了防止攻击者一次破坏整个数据库。盐的长度并不意味着增加破解存储密码的难度。这是为了确保你的 salt 与 Internet 上的其他人相比是相当独特的,并且(如果你做得对的话)你的两个用户不会有相同的 salt。
想象一下,您有 20 个用户,他们的密码都是“上帝”。考虑以下场景:
密码是未加盐
的 攻击者可以使用预先计算的表格在很短的时间内破解一个用户的密码。最重要的是,一旦他拥有 20 个中的第一个,他还将拥有其他 19 个,因为它们的哈希值相同。
密码是加盐的。使用的盐相当短。所有用户使用相同的盐。
攻击者可能需要寻找一点,但可能会遇到专门为您的配置制作的预计算表。在那之后,请参见方案 1。
密码是加盐的。使用的盐相当浓。所有用户使用相同的盐。
很有可能,攻击者不会在 Internet 上为您的系统找到预先计算的表。他必须自己做一个。这将需要一些额外的时间。然而,完成之后,我们又回到了场景 1。
因此,请使用长盐并使它们对每个用户都是唯一的。但是,如果个人用户使用“上帝”作为他们的密码,就不要指望它对他们有很大帮助。
太长的盐不会降低安全性。太短的盐会降低安全性。
随着盐变得更长,安全性将会提高。在某些时候,您将越过边界,在那里您开始随着盐长度的增加而获得递减收益。最终你将跨越另一个边界,更长的盐不会增加任何安全性。
然而,由于更长的盐没有任何显着的成本,没有理由停止增加长度,直到你到达第二个边界。即使您要增加盐的长度,唯一的缺点是在存储和处理时间方面的额外成本很小。
可悲的是,盐的长度通常低于两个阈值中的较低者。
那么这两个门槛是什么?
较低的阈值由用户数量和盐的目的决定,对于任何用户选择的每个密码都是不同的。如果我们保守估计,全球用户数量少于 10^10,每个用户拥有少于 10^2 个系统的密码,并且在其一生中更改此密码的次数少于 10^3 次。这意味着总共将有少于 10^15 个密码。鉴于此,人们可能会错误地得出结论,盐中的 50 位熵足以保证永远不会有两种盐重复,但由于生日悖论,我们必须将这个数字加倍。
因此,一旦盐的长度超过 100 位,我们就会开始看到在增加安全性方面的收益递减。100 位阈值涉及大量猜测。下一个阈值涉及的猜测要少得多。盐中超过 100 位的熵仍然可以提高安全性,但幅度不大。
一旦盐增长到比底层散列函数的输出长,则不再增加它的安全性。阈值取决于散列函数,典型散列的范围为 128 到 512 位。
请记住,通常每个字符使用 6 位熵生成盐,因此您需要 86 个盐字符才能达到 512 位熵。
从安全角度来看,盐的唯一重要属性是它是全球唯一的。长度可能会影响盐的独特性,但从任何其他角度来看都无关紧要。假设它对任何事情都有积极或消极的影响,那就是要求盐执行它从未打算服务的功能。
因此,盐应该足够长以合理地确保唯一性,仅此而已。假设您的盐具有良好的独特性,则不会再对安全性产生积极或消极的影响,但肯定会浪费存储空间。
其他人评论了盐和密码的正确使用,但也许在哈希函数上添加一个词很有用,因为您的问题似乎暗示了对它们工作方式的某种不正确的直觉。
根据设计,一个好的密码散列函数不应该让您根据散列值本身猜测输入的相似程度。否则,可以通过逐渐减小这个距离来反转它,这比纯粹的暴力猜测成本要低得多。所以 hash(salt1 + “12345”) 不应该更类似于 hash(salt1 + “67890”) 或 hash (“12345”) 而不是 hash(salt2 + “67890”)。
salt 的重点是确保输入(以及哈希)不相同,即使两个帐户碰巧使用相同的密码,但相似性不应该成为问题。