存储密码时推荐使用哪种哈希算法?

18

考虑到MD5已知的弱点以及SHA1在最近(2009年5月)被讨论的弱点,新程序应该如何对其密码进行加盐和哈希处理?

我看过建议使用SHA-256和SHA-512。

主要使用Ruby on Rails编程并使用PostgreSQL - 但其他语言和环境可能也需要计算密码哈希值。


2
谢谢Martin,我明白了。这是一个狭窄的问题,值得一个简洁的答案。 - Hissohathair
4个回答

20

SHA-256和SHA-512在可预见的未来是安全的。它们属于SHA-2家族,迄今为止还没有发现针对该家族的攻击。这个维基百科页面称Unix和Linux供应商正在转向使用SHA-2来进行密码的安全哈希。SHA-3家族拥有更强的算法,但要到2012年后才会准备好。

P.S: 除非您要隐藏政府的秘密特工名称,否则使用SHA-1也是安全的,但如果可以不费力地使用SHA-2,那就使用SHA-2吧。


2
PKCS#5(http://www.rsa.com/rsalabs/node.asp?id=2127)讨论了一些其他有用的信息(如迭代),读者可能会考虑。 - atk
@Noon Silk:目前需要多少计算能力才能破解它? - Eli Bendersky
@Noon Silk:根据那个页面,这个break目前只是理论上的(即找到了比暴力/生日攻击更快的方法)。话说,我的原帖是一年前的了,我完全预计不久的将来P.S.会变得非常错误。 - Eli Bendersky
1
@Eli: 注意这次攻击也是6年前的,所以目前进展情况不太清楚。我的意思是,你的主帖很好,我没有给你投反对票,但是我不同意你的最后一句话。可能没有必要继续讨论了,我的评论已经发表,信息也已提供。 - Noon Silk
100台现代电脑可以在1天内从其sha256哈希中破解一个8个字符长的密码。如今使用sha256作为密码的方式与明文存储密码并没有太大区别。 - undefined
@Klesun:如果你的密码只有8个字符,那么哈希算法的帮助就不大了。你只需要暴力破解一个由8个可打印字符组成的序列,而且还有一些启发式方法可以大大减小搜索空间。 - undefined

18

使用像bcrypt这样的慢函数。这里是来自Phusion团队的一篇文章。


9

2
我刚刚阅读了100篇关于这个主题的文章和问题,似乎大家都认为RFC2898或任何其他多次迭代的解决方案(例如BCrypt)是正确的选择。但是Rfc2898DeriveBytes基于SHA-1,这不会过时吗?而且,即使它看起来很棒,BCrypt似乎没有“验证”。此外,Rfc2898DeriveBytes没有实现IDisposable,看起来它很容易泄漏明文密码到内存中。我的实际需求并不是那么偏执,但我想衡量每种方法的安全性。你对此有什么看法?谢谢! - Spiky

-4

你应该一起使用哈希用户名、密码和盐,例如:

hash(length(username)+"_veryuniquesalt4rtLMAO"+username+password)

这样,由于盐的存在,您的数据库不会受到任何现有彩虹表的攻击,并且使用用户名和密码哈希后,也不可能为您特定的哈希方法创建彩虹表。

使用“慢速”哈希算法将更好地保护密码,就像它们更复杂一样,但这是一种权衡,一旦您决定了某个特定的缓慢程度,当您需要其他性能时,您不能轻易地缩小规模。

还可以使用JavaScript在客户端进行缓慢的哈希处理,这样就不会成为性能问题,但是该方法当然需要启用JavaScript。

无论您选择什么,稍微慢一点的哈希处理都比没有好得多,使用1毫秒而不是1微秒,您的保护强度将增加1000倍。

您可以使用bcrypt,或者可以让传统的哈希算法执行大量额外的工作,只需确保额外的工作不是主要的字符串连接即可。

最终,最好不要让您的数据库被盗,因为很多密码都太弱了,无论您做什么,都很容易被提取。


2
请注意,在哈希中包括用户名可以防止更改用户名。根据系统要求,这可能是可取的,也可能不可取。在不可取的情况下,使用uid(或guid或等效项)将是一种替代方法。 - atk
1
您只需让用户输入密码以更改用户名,这也是最佳实践。 - aaaaaaaaaaaa
2
你的代码中有一个非常微妙的错误 - 你绝对不应该在哈希表中连接数据。H(x + y + z) 会导致长度扩展攻击。相反,你应该使用 H(H(x + y + z)) 或者 H(H(x) + H(y) + H(z))。 - Michael Howard-MSFT
4
这并不是一个好的建议(盐值不应该是固定的字符串,每个密码都应该有一个盐值,并且每次更改密码时都应该随机生成)。而且这也没有回答问题,问题具体在于使用哪种哈希函数。 - caf
1
关于算法需要说的都已经说了,我不需要像鹦鹉一样重复别人说过的话。用户名+网站特定字符串可以生成完全独特的盐值,这已经是最好的了。你的方法也能实现同样的效果,但没有更多的优势。 - aaaaaaaaaaaa
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接