关于哈希:盐渍密码:最佳实践?

Salting Your Password: Best Practices?

我一直很好奇…当为散列添加密码时,哪一个更好:前缀或后缀?为什么?或者只要你盐,它就重要吗?

解释:我们现在(希望)都知道,在散列密码以便存储在数据库中之前,我们应该盐渍一个密码[编辑:这样你就可以避免最近发生在杰夫·阿特伍德身上的事情]。通常,这是通过在通过哈希算法传递密码之前将salt连接到密码来完成的。但是例子不尽相同…有些例子在密码前加上salt。一些示例在密码后添加salt。我甚至见过一些试图把盐放在中间的东西。

那么,哪种方法更好,为什么呢?有没有一种方法可以减少哈希冲突的可能性?我的谷歌搜索没有对这个问题做一个像样的分析。

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


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

你应该考虑这三件事:

  • 对于您存储的每个密码,salt必须是不同的。(这是一个很常见的误解。)
  • 使用加密安全的随机数生成器。
  • 选择足够长的盐。想想生日的问题。
  • DaveSherohman对另一个问题给出了一个很好的答案:为什么你应该使用随机生成的盐而不是用户名(或其他个人数据)。如果你遵循这些建议,把盐放在哪里真的没关系。


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

    事实上,它是应该打败彩虹桌的。

    我提到的威胁模型是这样一种场景,在这个场景中,对手可以在密码上附加/预先准备彩虹表的普通盐。(比如说国安局)你猜他们要么追加要么预先准备好,但不是两者都有。这太傻了,猜测也很糟糕。

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

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


    真正的答案是,这两个都是错误的,似乎没有人提及。如果您正在实现自己的加密,无论您认为自己正在做的某个部分多么微不足道,都会出错。

    HMAC是一种更好的方法,但是即使你使用类似于sha-1的方法,你也已经选择了一种算法,因为它的速度设计不适合密码散列。使用类似bcrypt或者scrypt的东西,把问题完全从你的手中解决掉。

    哦,甚至不要考虑将得到的哈希值与编程语言或数据库字符串比较实用程序进行比较,以获得相等的结果。如果字符不同,则按字符比较和按false比较短路。因此,现在攻击者可以使用统计方法来尝试一次找出哈希是什么,一个字符。


    这不应该有什么区别。无论你把盐放在哪里,杂烩都不容易猜出来。由于有意采用非线性,哈希冲突既罕见又不可预测。如果这对安全性有影响,那就意味着散列问题,而不是盐渍问题。


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

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


    首先,术语"彩虹表"一直被滥用。"彩虹"表只是一种特定的查找表,它允许对键进行特定类型的数据压缩。通过交换空间计算,可以将需要1000 TB的查找表压缩1000次,以便将其存储在较小的驱动器上。

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

    @onebyone.livejournal.com网站:

    The attacker has 'rainbow tables' consisting not of the hashes of dictionary words, but of the state of the hash computation just before finalising the hash calculation.

    It could then be cheaper to brute-force a password file entry with postfix salt than prefix salt: for each dictionary word in turn you would load the state, add the salt bytes into the hash, and then finalise it. With prefixed salt there would be nothing in common between the calculations for each dictionary word.

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

    此外,密码散列算法(如pbkdf)多次组成散列函数(建议至少迭代pbkdf-2 1000次,每次迭代应用sha-1两次),这使得这种攻击加倍不切实际。


    如果平台有提供程序,则返回bcrypt哈希。我喜欢你不用担心盐的生成,如果你想的话,你可以让它们更强壮。


    在密码中插入一个任意数量的字符是最不期望的情况,因此在社会上是最"安全"的,但在一般情况下,只要您使用长的、唯一的每个密码字符串来输入salt,它就不太重要。