我应该使用什么算法将密码散列到数据库中?[复制]
-
02-07-2019 - |
题
这个问题在这里已经有答案了:
- 安全密码哈希 9 个答案
有没有 任何事物 是否可用,不易损坏?
解决方案
这个 2008 年的答案现在已经过时了。 SHA(所有变体)现在很容易被破坏,现在(截至 2013 年 1 月)最佳实践是使用密钥延伸哈希(如 PBKDF2)或理想情况下使用 RAM 密集型哈希(如 比特密码)并添加每个用户的盐。
第2、3、4点仍然值得关注。
请参阅 IT 安全SE 站点 了解更多。
2008年原答案:
使用经过验证的算法。SHA-256 在数据库中使用 64 个字符,但在列上有索引不是问题,而且它是经过验证的哈希值,比 MD5 和 SHA-1 更可靠。它也作为标准安全套件的一部分在大多数语言中实现。不过,如果您使用 SHA-1,也不必担心。
不要只对密码进行哈希处理,还要将其他信息放入其中。您经常使用“用户名:密码:盐”或类似的哈希值,而不仅仅是密码,但如果您使用此方法,那么您将更难进行字典攻击。
安全是一个艰难的领域,不要认为你可以发明自己的算法和协议。
不要编写诸如“[AddUser] GeorgeBush:Rep4Lyfe:ASOIJNTY is xyz”之类的日志
其他提示
密码学和密码存储的第一条规则是“不要自己发明它,”但如果你必须这样做,那么为了获得表面上的安全性,你必须做的绝对最低限度是:
基本规则:
- 切勿存储纯文本密码(这意味着您也永远无法显示或传输它。)
- 切勿通过不安全的线路(纯文本、编码或散列)传输存储的密码表示形式。
- 速度是你的敌人。
- 定期重新分析和 改进您的流程 随着硬件和密码分析的改进。
- 密码学和过程是 很小 解决方案的一部分。
- 失败点包括:存储、客户端、传输、处理、用户、法律保证、入侵和管理员。
脚步:
- 强制执行一些合理的最低密码要求。
- 经常更改密码。
- 使用你能得到的最强的哈希值 - SHA-256 被建议在这里。
- 将密码与 固定盐 (整个数据库也一样)。
- 将上一步的结果与 独特的盐 (可能是用户名、记录 ID、GUID、长随机数等)存储并附加到该记录。
- 多次运行哈希算法 - 好像1000+次. 。理想情况下,每次与前一个哈希值一起包含不同的盐。速度是你的敌人,多次迭代会降低速度。每隔一段时间就会加倍迭代(这需要捕获新的哈希值 - 下次他们更改密码时执行此操作。)
哦,除非您运行 SSL 或其他线路安全,否则不要允许您的密码以纯文本形式传输。如果您只是将客户端的最终哈希值与存储的哈希值进行比较,则也不允许以纯文本形式传输。您需要向客户端发送一个随机数(使用过一次的数字),并让他们使用生成的散列(使用上面的步骤)散列该随机数,然后他们向您发送该随机数。在服务器端,您运行相同的进程,并查看两个一次性哈希值是否匹配。然后处理掉它们。有更好的方法,但这是最简单的方法。
2013 年 1 月更新
最初的答案是从 2008 年开始的,在过去 5 年里事情发生了一些变化。云计算和强大的并行处理器图形卡的随时可用意味着,最多 8 或 9 个字符散列为 MD5 或 SHA1 的密码现在可以轻松破解。
现在,长盐是必须的,就像 SHA512 这样更难的东西。
然而,所有 SHA 变体哈希值均设计用于通信加密 - 来回消息,每条消息都经过加密,因此它们被设计为 快速地.
在密码哈希世界中,这种设计是一个很大的缺点,因为哈希生成的速度越快,生成大量哈希所需的时间就越少。
像 SHA512 这样的快速哈希每秒可以生成数百万甚至数十亿次。加上廉价的并行处理,密码的每一种可能的排列都成为绝对必须的。
键拉伸是解决这个问题的一种方法。密钥拉伸算法(如 PBKDF2)会应用更快的哈希(如 SHA512)数千次,通常会导致哈希生成需要 1/5 秒左右的时间。登录的人不会注意到,但如果每秒只能生成 5 个哈希值,那么暴力攻击就会更加困难。
其次应该有 总是 是每个用户的随机盐。这可以作为第一个随机生成 n 哈希的字节(然后在构建要比较的哈希之前将其剥离并添加到要检查的密码文本中)或作为额外的数据库列。
所以:
我应该使用什么算法将密码散列到数据库中?
按键拉伸 减慢哈希生成速度。我可能会选择 PBKDF2。
每用户盐 意味着每个用户都会遭受一次新的攻击,并且需要一些工作来弄清楚如何获取盐。
计算能力和可用性正在呈指数级增长 - 这些规则很可能在未来 4 年内再次发生变化。如果您需要面向未来的安全性,我会研究 bcrypt/scrypt 风格的哈希值 - 这些哈希值采用较慢的密钥拉伸算法,并添加一个使用大量 RAM 来生成哈希值的步骤。使用如此多的 RAM 会降低廉价并行处理器的效率。
原始日期 2008 年 9 月(保留以便评论有意义)
MD5+salt 或 SHA1+salt 并不是“容易破解的”——大多数 hack 都依赖于巨大的彩虹表,而这些在使用 salt 后变得不太有用 [update, now they are]
.
MD5+salt 是一个相对较弱的选择,但它不会轻易被破坏 [update, now it is very easy to break]
.
SHA2 一直到 512 - 使用现成的工具包几乎不可能破解它 [update, pretty easy up to 9 char passwords now]
- 虽然我确信某个军事掩体里有一个克雷可以做到这一点 [You can now rent this 'Cray' from Amazon]
MD5 或 SHA 与每个条目随机生成的盐值相结合
正如前面提到的,这里不应该使用简单的哈希算法,原因是:
http://arstechnica.com/security/2012/08/passwords-under-assault/
所以使用其他东西,例如 http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx
所有散列算法都容易受到“字典攻击”。这就是攻击者拥有一个非常大的可能密码字典的地方,并且他们对所有这些密码进行哈希处理。然后,他们查看这些哈希值是否与他们想要解密的密码的哈希值相匹配。这种技术可以轻松测试数百万个密码。这就是为什么您需要避免任何可能远程可预测的密码。
但是,如果您愿意接受字典攻击的威胁,MD5 和 SHA1 就足够了。SHA1 更安全,但对于大多数应用程序来说,这实际上并不是一个重大改进。
MD5 / SHA1 哈希值都是不错的选择。MD5 比 SHA1 稍弱。