163

我一直很好奇......在为哈希加密密码时哪个更好:前缀还是后缀?为什么?或者,只要你加盐,这有关系吗?

解释一下:我们现在(希望)都知道,我们应该在对密码进行哈希处理以存储在数据库中之前对密码进行加盐[编辑:这样你就可以避免像最近发生在 Jeff Atwood 身上的事情]。通常这是通过在将盐传递给散列算法之前将盐与密码连接起来来完成的。但例子各不相同......一些例子在密码前加上盐。一些示例在密码后添加盐。我什至见过一些人试图把盐放在中间。

那么哪种方法更好,为什么?有没有一种方法可以减少哈希冲突的机会?我的谷歌搜索还没有对这个主题进行像样的分析。

编辑:很好的答案伙计们!对不起,我只能选择一个答案。:)

4

8 回答 8

115

前缀或后缀无关紧要,它只是为密码添加一些熵和长度。

你应该考虑这三件事:

  1. 对于您存储的每个密码,盐必须不同。(这是一个很常见的误解。)
  2. 使用加密安全的随机数生成器。
  3. 选择足够长的盐。想想生日问题。

Dave Sherohman对另一个问题有一个很好的回答,为什么你应该使用随机生成的盐而不是用户名(或其他个人数据)。如果您遵循这些建议,那么您将盐放在哪里并不重要。

于 2009-03-23T19:39:35.170 回答
27

我认为这都是语义。将其放在之前或之后并不重要,除非针对的是非常具体的威胁模型。

它在那里的事实应该会击败彩虹桌。

我提到的威胁模型将是攻击者可以将彩虹表附加/附加到密码的情况。(比如美国国家安全局)你猜他们要么附加了它,要么附加了它,但不是两者兼而有之。这很愚蠢,而且是一个糟糕的猜测。

最好假设他们有能力存储这些彩虹表,但不能存储密码中间散布着奇怪盐的表。在那种狭隘的情况下,我猜想穿插是最好的。

就像我说的。是语义。为每个密码选择一个不同的盐,一个长盐,并在其中包含奇数字符,如符号和 ASCII 码:©¤¡

于 2009-03-23T19:41:25.683 回答
19

似乎没有人提到的真正答案是两者都是错误的。如果您正在实施自己的加密,无论您认为自己在做什么微不足道的部分,您都会犯错误。

HMAC是一种更好的方法,但即便如此,即使您使用的是 SHA-1 之类的东西,您也已经选择了一种不适合密码散列的算法,因为它的设计是为了速度。使用像bcrypt或可能的scrypt之类的东西,完全摆脱你的问题。

哦,甚至不要考虑将生成的哈希值与您的编程语言或数据库字符串比较实用程序进行比较。那些比较字符和短路的字符就false好像字符不同一样。所以现在攻击者可以使用统计方法来尝试计算哈希是什么,一次一个字符。

于 2012-07-05T21:33:02.323 回答
9

它不应该有任何区别。无论你把盐放在哪里,哈希都不会更容易被猜到。由于故意非线性,哈希冲突既罕见又不可预测。如果它对安全性产生影响,则表明散列存在问题,而不是加盐问题。

于 2009-03-23T19:37:36.610 回答
7

如果使用加密安全散列,无论您是前置还是后缀都无关紧要;散列的一点是源数据中的单个位更改(无论在哪里)都应该产生不同的散列。

不过,重要的使用长盐,使用适当的加密 PRNG 生成它们,并拥有每个用户的盐。在数据库中存储每个用户的盐不是安全问题,使用站点范围的哈希.

于 2009-03-23T20:55:27.720 回答
5

首先,“彩虹表”一词一直被误用。“彩虹”表只是一种特定类型的查找表,它允许对键进行特定类型的数据压缩。通过用计算换取空间,可以将占用 1000 TB 的查找表压缩一千倍,以便将其存储在更小的驱动器上。

您应该担心哈希到密码查找表、彩虹或其他方式。

@onebyone.livejournal.com:

攻击者的“彩虹表”不是由字典单词的哈希组成,而是在完成哈希计算之前的哈希计算状态。

然后,使用后缀 salt 暴力破解密码文件条目可能比前缀 salt 更便宜:依次为每个字典单词加载状态,将 salt 字节添加到哈希中,然后完成它。使用前缀盐,每个字典单词的计算之间没有任何共同点。

对于线性扫描输入字符串的简单哈希函数,例如简单的线性同余生成器,这是一种实用的攻击。但是一个加密安全的散列函数被故意设计为多轮,每轮都使用输入字符串的所有位,因此在第一轮之后计算在添加盐之前的内部状态是没有意义的。例如,SHA-1 有 80 轮。

此外,像 PBKDF 这样的密码散列算法多次组合它们的散列函数(建议迭代 PBKDF-2 至少 1000 次,每次迭代应用 SHA-1 两次)使得这种攻击更加不切实际。

于 2009-03-24T00:16:31.510 回答
4

如果平台有提供者,则为 BCrypt 哈希。我喜欢你不用担心产生盐的方式,如果你愿意,你可以让它们变得更强壮。

于 2009-03-23T19:40:44.780 回答
2

在密码中插入任意数量的字符是最不期望的情况,因此在社交上最“安全”,但在一般情况下它真的不是很重要,只要你使用长的,每个密码唯一盐的字符串。

于 2009-03-23T20:41:32.993 回答