我一直很好奇…当为散列添加密码时,哪一个更好:前缀或后缀?为什么?或者只要你盐,它就重要吗?
解释:我们现在(希望)都知道,在散列密码以便存储在数据库中之前,我们应该盐渍一个密码[编辑:这样你就可以避免最近发生在杰夫·阿特伍德身上的事情]。通常,这是通过在通过哈希算法传递密码之前将salt连接到密码来完成的。但是例子不尽相同…有些例子在密码前加上salt。一些示例在密码后添加salt。我甚至见过一些试图把盐放在中间的东西。
那么,哪种方法更好,为什么呢?有没有一种方法可以减少哈希冲突的可能性?我的谷歌搜索没有对这个问题做一个像样的分析。
编辑:很好的答案,伙计们!对不起,我只能选一个答案。:)
- See also:stackoverflow.com/questions/1645161/…
- @Jacco:Awesome Input.谢谢
- 你可以用这个:加密.密码
- @OMU:嗯…使用4-字节随机盐,并用密码封存。拉特尔是克里夫尔,但前者…我想这可能是一个小小的低价。不过,如果你想快点,密码已经有了。
- @Randolpho you can specificy the salt size,4 byte is by default
- 你说得对我想念这个。
- 最佳做法是使用加密函数为你盐渍,使用的是PBKDF2(标准)、BCRYPT或甚至Scrypt。谢谢Stephen指点这个
- 所有的标准密码都有很好的组合,所以你不必担心这个。如果你不使用标准密码,请输入一个。
- @OMU Bad recommendation.(1)SHA-1的一个单一特征太快了,你应该至少使用10000,甚至是很漂亮的软弱。(2)Default salt is too small.8 Bytes is minimum and 16 is recommended.
- Related:does prepared a salt to the password instead it in the middle decrease security?,salt place prior to one-way hash,how to securely hash passwords?
- 谢谢你的链接我喜欢最后一个最好的答案。
- Please fix the link.its not working: 124;
- @Shekharpankaj both links in my post still work perfectly for me.
前缀或后缀是不相关的,它只是增加一些熵和长度的密码。
你应该考虑这三件事:
对于您存储的每个密码,salt必须是不同的。(这是一个很常见的误解。)
使用加密安全的随机数生成器。
选择足够长的盐。想想生日的问题。
DaveSherohman对另一个问题给出了一个很好的答案:为什么你应该使用随机生成的盐而不是用户名(或其他个人数据)。如果你遵循这些建议,把盐放在哪里真的没关系。
- 作为一个非安全专家,我并没有得到第一点。hashed_pw=hash(cantend_salt+login+password)是否足够,或者是否需要将salt与密码一起存储?有什么建议吗?
- 我添加了一个旧问题的链接,请阅读这些答案。基本上,通过不对每个密码使用不同的随机salt,您将承担不必要的安全风险,这在将来可能是一个真正的问题。
- 如果你读到他的答案,他会说你应该使用随机的salt来对比他们的用户名或其他用户数据。有一侧宽的随机盐仍然有效。
- 应该足够安全,除非你有很多用户和黑客为你的网站创建了一个彩虹表。
- 是的,仍然很安全。您可能只是希望它更安全,这样您就可以为每个用户生成一个salt。
- 站点范围的随机salt是不好的,因为攻击者可以预计算彩虹表并获取整个用户数据库。如果您不理解这一点,请不要编写登录/安全系统:)-您需要每个用户的盐。
- 是的,每用户盐。理想情况下,存储每个用户的迭代(这样可以增加一段时间内使用的迭代次数)。任何像样的框架都有这个内置的。(.NET具有密码派生字节,它将为您处理所有内容。)
- 你根本不需要盐。你应该吃盐。至于你是否需要每个用户的盐,这一切都取决于有人破坏你的用户帐户的动机。如果有一个巨大的激励,你需要每个用户,因为这将是非常昂贵的妥协所有用户。
- "你根本不需要盐"-见鬼,你根本不需要散列,如果你认为你可以保守你的数据库秘密;-)
- 如果你在设计任何类型的安全系统,那么不使用每个用户的salt是很愚蠢的。你的网站可能不是特别有趣,但考虑到用户在多个网站上使用相同的密码…试图保护数据库的安全往往会失败:)
- 盐不能抵御字典攻击,只能抵御彩虹表。但他说得对,这样的攻击要慢得多。
- 当然,盐可以防止字典攻击,这正是通过使它们慢得多。密码中使用盐的时间比彩虹表早得多。为了减缓字典攻击,专门添加了salts,防止攻击者对密码进行一次哈希处理,然后将其与所有用户进行比较。
- 攻击者可以预先计算多个常用密码的md(pass),然后以较低的价格计算密码数据库中的每个salt的md(pass+salt),因为消息摘要以增量方式工作,以支持流媒体。
我认为这都是语义学。把它放在前面或后面并不重要,除非是针对一个非常具体的威胁模型。
事实上,它是应该打败彩虹桌的。
我提到的威胁模型是这样一种场景,在这个场景中,对手可以在密码上附加/预先准备彩虹表的普通盐。(比如说国安局)你猜他们要么追加要么预先准备好,但不是两者都有。这太傻了,猜测也很糟糕。
最好假设他们有能力存储这些彩虹表,但不能假设在密码中间散布着奇怪的盐的表。在这种狭隘的情况下,我猜想穿插最好。
就像我说的。这是语义学。为每个密码选择一个不同的salt,一个长salt,并在其中包含奇数字符,如符号和ASCII代码:??
- @一个接一个,该死!他发现了我的密码盐!
- @塞缪尔:我不知道你们的情况,但我们用"12345"来做盐。:)
- @一对一有效。我真正的意思是"普通",因为"字符集y中长度x以下的所有盐",其中x,y是合理的;比如20个字符和字母数字大小写。可以扩展为说长度z(比如160)下的所有十六进制字符串,因为我认为由哈希组成的彩虹表是有用的。
- @伦道夫:嘿,那也是我的盐!几率有多大?
- 确保salt是不可预测的/随机的:stackoverflow.com/questions/1645161/…
- 加盐密码远早于彩虹表。
真正的答案是,这两个都是错误的,似乎没有人提及。如果您正在实现自己的加密,无论您认为自己正在做的某个部分多么微不足道,都会出错。
HMAC是一种更好的方法,但是即使你使用类似于sha-1的方法,你也已经选择了一种算法,因为它的速度设计不适合密码散列。使用类似bcrypt或者scrypt的东西,把问题完全从你的手中解决掉。
哦,甚至不要考虑将得到的哈希值与编程语言或数据库字符串比较实用程序进行比较,以获得相等的结果。如果字符不同,则按字符比较和按false比较短路。因此,现在攻击者可以使用统计方法来尝试一次找出哈希是什么,一个字符。
- 关于最后一段:攻击者如何获得关于比较失败的确切字符数的任何信息?这没有道理……
- 你既正确又不正确。定时攻击是真实的,并且已经反复证明是可行的,即使是在可变延迟网络连接上,也具有令人恐惧的准确性,以准确确定比较失败的地方。也就是说,时间攻击实际上并不适用于普通密码散列,因为在计算上找不到只改变输出小部分的输入。
这不应该有什么区别。无论你把盐放在哪里,杂烩都不容易猜出来。由于有意采用非线性,哈希冲突既罕见又不可预测。如果这对安全性有影响,那就意味着散列问题,而不是盐渍问题。
- 哈希冲突取决于哈希的大小。由于生日问题,碰撞很可能发生。
- 只有在截断结果时。不管怎样,我仍然坚持这样的观点,即在salt所在的位置上它不会有任何区别,因为散列的目的是使输入和输出之间的关系不包含模式。
如果使用加密的安全散列,那么无论是修复前还是修复后都不重要;散列的一个要点是源数据中的单个位更改(无论在何处)都应产生不同的散列。
但是,重要的是使用长盐,用适当的密码prng生成它们,并拥有每用户的盐。在数据库中存储每个用户的盐不是一个安全问题,使用站点范围的哈希是。
- 错误的anwser:攻击者可以预先计算许多常用密码的md(pass),然后非常便宜地计算md(pass+salt),因为消息摘要以增量方式工作以支持流。
首先,术语"彩虹表"一直被滥用。"彩虹"表只是一种特定的查找表,它允许对键进行特定类型的数据压缩。通过交换空间计算,可以将需要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哈希。我喜欢你不用担心盐的生成,如果你想的话,你可以让它们更强壮。
- 正如我所知,bcrypt散列需要加盐,就像其他散列方案一样。
在密码中插入一个任意数量的字符是最不期望的情况,因此在社会上是最"安全"的,但在一般情况下,只要您使用长的、唯一的每个密码字符串来输入salt,它就不太重要。