给密码加盐: 最佳实践?

我一直很好奇... 在为散列(hashing)设置密码时,哪个更好: 前缀还是后缀?为什么?还是只要你撒盐就行了?

解释一下: 我们现在都(希望)知道,在我们散列密码以便在数据库中存储之前,我们应该使用 密码[ 编辑:] ,因此您可以避免使用像 杰夫 · 阿特伍德最近的遭遇这样的密码。通常,这是通过在通过散列算法传递之前将 salt 与密码连接起来完成的。但是这些例子各不相同... ... 有些例子在密码前面加盐。一些示例添加 salt 之后作为密码。我甚至见过有人把盐放在中间。

那么哪种方法更好呢? 为什么?有没有一种方法可以降低散列冲突的几率?我在谷歌上没有找到关于这个问题的正确分析。

编辑: 很棒的回答,伙计们! 很抱歉我只能选择一个答案

86159 次浏览

应该没什么区别。无论你把盐放在哪里,散列都不容易猜到。散列碰撞很少见,而且不可预测,因为它是故意非线性的。如果它对安全性有影响,那就说明是散列的问题,而不是盐的问题。

前缀或后缀是不相关的,它只是增加一些熵和长度的密码。

你应该考虑以下三点:

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

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

如果平台具有提供程序,则使用 BCrypt hash 。我喜欢你不用担心盐的制造如果你愿意,你可以让它们变得更强。

我认为这都是语义学的问题,把它放在前面或后面并不重要,除非是针对一个非常具体的威胁模型。

事实上,它的存在是为了打败彩虹桌。

我提到的威胁模型是这样一种场景: 对手 可以在密码后面附加/预先加入了普通盐的彩虹表。(比如国家安全局)你猜他们要么有附加条款,要么有预设条款,但不是两者都有。太傻了,而且猜得也不准。

我们最好假设他们有能力存储这些彩虹桌子,但是,比如说,密码中间穿插着奇怪盐的桌子。在 那个狭义的情况下,我会推测穿插将是最好的。

就像我说的。这是语义学。每个密码选择一个不同的 salt,一个长的 salt,并在其中包含奇怪的字符,如符号和 ASCII 码:

向密码中插入一个任意数量的字符是最不希望出现的情况,因此也是社会上最“安全”的情况,但是在一般情况下,只要您使用长的、每个密码只有一个字符串作为 salt,这种情况就真的不是很重要。

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

然而,的重要之处在于使用长盐,使用适当的加密 PRNG 生成长盐,并且具有每个用户的盐。使用站点范围的哈希 在数据库中存储每个用户的盐是一个安全问题。

首先,“彩虹桌”这个词一直被误用。一个“彩虹”表只是一个特定的 abc 0查找表,一个允许特定种类的数据压缩键。通过以计算换空间,一个需要1000TB 的查找表可以被压缩一千次,以便能够存储在一个更小的驱动器上。

你应该担心散列密码查找表,彩虹或其他。

@ onebyone. livejournal. com:

攻击者拥有“彩虹表”,它不包含字典单词的散列,而是在完成散列计算之前的散列计算状态。

然后,使用后缀 salt 强制输入密码文件条目可能比使用前缀 salt 更便宜: 对于每个字典单词,您依次加载状态,将 salt 字节添加到散列中,然后最终确定它。如果使用前缀 salt,那么对每个字典单词的计算就没有任何共同之处。

对于一个简单的散列函数,它可以线性地扫描输入字符串,比如一个简单的线性同余方法,这是一种实用的攻击。但是一个加密安全的散列函数被故意设计成有多个回合,每个回合都使用输入字符串的所有位,因此在第一个回合之后,计算内部状态 只是之前加上 salt 是没有意义的。比如 SHA-1有80发子弹。

此外,像 PBKDF 这样的密码哈希算法多次构成它们的哈希函数(建议最少迭代1000次 PBKDF-2,每次迭代应用 SHA-1两次) ,这使得这种攻击加倍不切实际。

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

HMAC 是一种更好的方法,但是即使您使用了类似 SHA-1的算法,您也已经选择了一种由于其速度设计而不适合密码哈希的算法。使用像 地下室或可能的 脚本的东西,把问题从你的手完全。

哦,甚至不要考虑将结果哈希值与您的编程语言或数据库字符串比较实用程序进行比较。那些比较字符的字符和短路作为 false如果字符不同。因此,现在攻击者可以使用统计方法来尝试并计算出散列是什么,一次一个字符。