腌制您的密码:最佳实践?
我一直很好奇…哪个更好的时候,哈希密码:前缀,或后缀? 为什么? 或者是否重要,只要你盐?
解释一下:我们(希望)现在知道我们应该在密码存储到数据库之前先encryption一个密码[ 编辑:所以你可以避免像最近发生的事情那样的事情 ]。 通常这是通过在将密码与哈希algorithm传递之前串接盐和密码来完成的。 但是这些例子各不相同…有些例子在密码之前加了盐。 一些例子在密码后添加盐。 我甚至见过一些尝试把盐放在中间。
那么更好的方法是什么?为什么? 有没有一种方法可以减less哈希碰撞的机会? 我的谷歌search没有就这个问题做出体面的分析。
编辑:伟大的答案乡亲们! 对不起,我只能select一个答案。 🙂
前缀或后缀是不相关的,只是增加一些熵和长度的密码。
你应该考虑这三件事情:
- 对于您存储的每个密码,盐必须不同。 (这是一个很常见的误解。)
- 使用密码安全的随机数发生器。
- select足够长的盐。 想想生日问题。
Dave Sherohman回答了另一个问题,为什么你应该使用随机生成的盐而不是用户名(或其他个人数据)。 如果你遵循这些build议,放盐的地方确实无关紧要。
我认为这是所有的语义。 把它放在前面或后面并不重要,除非是针对一个非常具体的威胁模型。
事实上,这是应该打败彩虹桌。
我所提到的威胁模型就是敌人可以在密码后添加/附加普通盐的彩虹表。 (说美国国家安全局)你猜猜他们要么附加或prepended,但不是两个。 这很愚蠢,这是一个可怜的猜测。
假设他们有能力储存这些彩虹桌,而不是在密码中间穿插奇怪盐的桌子,这样会更好。 在这种狭隘的情况下,我猜想穿插是最好的。
就像我说的。 这是语义。 select一个不同的盐每个密码,一个长盐,并包括奇怪的字符,如符号和ASCII代码:©¤¡
没有人提到过真正的答案,就是两者都是错的 。 如果你正在执行你自己的encryptionalgorithm,不pipe你认为自己在做的是多么微不足道的部分,你都会犯错误。
HMAC是一个更好的方法,但即使如此,如果您使用的是SHA-1之类的东西,那么您已经select了一种algorithm,由于其devise的速度而不适合密码散列。 使用bcrypt或scrypt之类的东西,把问题完全从你手中解决。
呵呵,甚至不要考虑把你的编程语言或数据库string比较实用程序与平等的哈希进行比较。 如果字符不同,那么将字符和短路比较为false
。 所以现在攻击者可以使用统计方法来尝试一次一个字符地计算哈希是什么。
它不应该有任何区别。 无论你把盐放在哪里,散列都不会更容易被猜出。 哈希碰撞是非常罕见和不可预知的,因为有意非线性。 如果这对安全有所影响,那么这就意味着哈希的问题,而不是腌制。
如果使用encryption安全散列,则不论你是前置还是后置; 散列的一点是源数据中的单个位变化(不pipe在哪里)应该产生不同的散列。
然而,重要的是使用长盐,用适当的密码PRNG产生它们,并且具有用户盐。 在数据库中存储每个用户的盐不是一个安全问题,使用站点范围的散列是 。
BCrypt哈希如果平台有提供者。 我爱你如何不担心创造的盐,你可以使他们更强大,如果你想。
首先,“彩虹桌”一词一直被滥用。 “彩虹”表只是一种特殊的查找表,允许在键上进行特定types的数据压缩。 通过交换空间计算,一张需要1000TB的查找表可以被压缩一千次,以便可以将其存储在较小的驱动器驱动器上。
你应该担心哈希到密码查找表,彩虹或其他。
@ onebyone.livejournal.com:
攻击者拥有的“彩虹表”不是由字典单词的散列组成的,而是在完成散列计算之前的散列计算的状态。
然后使用后缀salt比前缀salt强制使用密码文件入口更便宜:对于每个字典单词,反过来,您将加载状态,将salt字节添加到散列中,然后最终确定它。 用前缀的盐,每个字典单词的计算之间没有什么共同之处。
对于通过inputstring线性扫描的简单哈希函数,如简单的线性同余生成器,这是一个实际的攻击。 但是密码安全的散列函数被故意devise为具有多个回合,每个回合都使用inputstring的所有位,因此在第一轮之后计算加盐之前的内部状态是没有意义的。 例如,SHA-1有80轮。
此外,像PBKDF这样的密码散列algorithm多次组合它们的散列函数(推荐将PBKDF-2迭代至less1000次,每次迭代应用SHA-1两次)使得这种攻击加倍不切实际。
在密码中插入任意数量的字符是最不可预料的情况,因此在社交上是最“安全”的,但是在一般情况下,只要您使用长密码,每个密码都是唯一的盐的string。