【问题标题】:Securely hash passwords - so much conflicting advice!安全地散列密码 - 这么多相互矛盾的建议!
【发布时间】:2011-10-16 07:41:48
【问题描述】:

我正在阅读很多关于如何安全存储密码的相互矛盾的建议。我所知道的肯定是不要使用 MD5!我见过有人提倡使用 PHP 的 bcrypt 函数,这似乎会占用服务器的处理器。我见过提倡盐的人,也见过不使用盐的人。

这一切都太不清楚了。是否有关于如何安全存储密码的真实可信的建议?

编辑:经过大量研究,我发现了一篇来自 ;login: 的文章,该文章相当深入地处理了该主题:http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf

【问题讨论】:

  • 这一切都基于意见。我只使用MD5。适合我的需要。
  • 真正的解决方案?不要存储密码。使用 OpenID 提供程序。 :-)
  • @imoda MD5 已知弱点
  • @TotalFrickinRockstarFromMars(感谢您让我输入!)不幸的是,外部提供商不适合这种情况。

标签: php hash passwords md5 salt


【解决方案1】:

这类似于这个问题:Methods for storing login information in database

可靠的建议:切勿以明文形式存储您的密码!

除此之外,您还有一些选择。正如我在对链接问题的回复中提到的,有两个阵营:让其他人存储您的身份验证数据或自己做。如果你决定自己做,那么你需要想出一个散列例程。这可能应该包括对您的密码进行加盐。

【讨论】:

    【解决方案2】:

    首先你需要使用一个好的散列函数,我建议使用 SHA-256。您可以像这样创建 SHA-256 哈希:

    $hash = hash('sha256', $password);
    

    此外,您还可以像这样使用盐渍:

    $salt = 'salt here';
    $hash = hash('sha256', $salt . $password);
    

    此外,您可以像这样使用 HMAC:

    $secret = 'your secret';
    $hmac = hash_hmac('sha256', $password, $secret);
    

    创建可靠哈希的最佳方法是通过加盐和迭代。 您应该循环上述函数,直到散列需要 200 毫秒。

    您也可以继续使用加密,但在大多数情况下这有点矫枉过正。

    【讨论】:

    • 您可以使用GRC 获取盐值。随机 ASCII 字符可以保持简单,任何超过 32 字节的长度都可以用于 SHA-256。
    • 为什么 SHA-256 适合散列密码?它被设计为快速。这对于散列密码不需要,因为它的计算成本并不高。与bcrypt比较。
    • bcrypt 是另一个不错的选择,但是通过加盐和迭代,您可以使用 SHA-256 获得同样好的结果。显然,如果您要设计核电站,bcrypt 和 sha-256 都无用,但对于休闲网站来说,它们绰绰有余。
    • 那么为什么建议使用bcrypt 并可能引入更多问题呢?安全性很难做到正确。 bcrypt 是由两个非常聪明的人设计的。
    • 我并不是建议不要使用 bcrypt,bcrypt 很棒,我承认这是另一个可行的选择。然而,对于一个小型项目,bcrypt 和 sha2 都足够好。 bcrypt 本身有几个缺点,例如密码的密码分析方法比散列函数的方法开发得更好。
    【解决方案3】:

    嗯,这有几个部分。

    1. 首先,您需要设法让访问您的数据库和密码变得困难,并确保它们的安全。这包括不使您的密码明文并且不使用对称加密算法。
    2. 您需要使用salt。这样做可以防止人们使用预先计算的查找表(即彩虹表)或类似http://md5.rednoize.com/ 的东西。为您的盐选择一些独特不可预测的数据。我通常使用随机的 32 位值,但我不会少用。
    3. 某些算法比其他算法更强大。这是通过几种方式定义的
      1. 计算速度有多快。越长越好。攻击者计算哈希的速度越快,暴力攻击的可能性就越大。
      2. 如果算法没有已知的弱点会减少搜索空间。例如,md5 哈希中的位数具有误导性,因为有known attacks 会减少实际搜索空间

    截至今天,我认为 SHA1 or SHA2 加盐在不久的将来是相当安全的。有一个名为 bcrypt 的实用程序使用了河豚的不对称变体,并内置了盐和计算费用的概念,可能值得一试。


    编辑:我想澄清一下什么是盐,因为在 SO 和网上存在很多对它的误解。

    什么是盐不是

    一个秘密,预先商定的字符串,你用密码散列。这是密钥,不是盐。

    什么是盐

    您在散列时将盐(每个散列唯一且不可预测)与您的密码一起包含,但您还包含它的未加密副本在散列之外,所以在稍后验证哈希时,您可以在对哈希之前给出测试密码时包含相同的盐,这样您就可以正确比较哈希。

    【讨论】:

    • 什么才是好的盐值?另外,简而言之,SHA算法之间有什么区别?是什么让一个比另一个更受欢迎?
    • 很好的一般解释。但是,您继续建议 SHA1/2,它设计为计算成本高(与 bycrpt 或多轮相比)——这与上面的 3.1 相反。
    • 好的盐是独特的不可预测的。因此,简而言之,好的盐是具有足够熵(本质上是长度)的随机数。什么是足够的?由你决定,我通常选择一个随机的 32 位数字作为盐。老实说,我对数学的了解还不够,无法具体告诉您 SHA1 和 SHA2 之间的区别,我会在这里听其他专家的意见,希望他们能帮助我改进我的答案。也许将这个问题发布到math.stackexchange.com... 或者我会:)
    • @pst 使用bcrypt - 如果我的应用程序在同一个共享主机环境中被许多人使用,这不会拖累性能吗?不是过早的优化,但如果有相同的选择,我只是不想故意构建慢代码。
    • @pst 你会推荐什么?我过去曾使用过多轮 sha,尽管也许我应该提一下。另外,我确实认为这真的取决于应用程序。正确加盐的 SHA2 哈希...我不认为它很弱。
    【解决方案4】:

    您可以使用 sha256。一个好的做法是在密码中添加额外的信息,例如用户名、用户 ID 或其他一些数据。这样,如果有人破解了你的数据库,就不可能使用现有的哈希数据库来找到密码。他们将不得不从零开始破解密码。

    【讨论】:

    • 这是一个开源应用程序,因此如果有人掌握了数据库表,他们也可以访问源代码并知道盐是如何计算的。我相信,这会使盐变得毫无意义。
    • 为什么 SHA-256 适合散列密码?它被设计为快速。这对于散列密码来说是不希望的,因为它的设计并不是计算成本高昂。与bcrypt比较。
    • 鉴于此,您将需要在您的计算机上安装一个单独的芯片来保存您的哈希算法。如果你设计一个银行网站,那是个好主意,但是对于普通的 web 开发者来说,这是不可能的。另外,如果被黑客访问了另一个数据库,那么很容易找到密码
    • Salt 即使是开源的,仍然很有用。散列是有损的,不同的文本可以有相同的散列。这意味着您可以使用多个密码进入系统,并且使用彩虹表之类的东西,如果您的哈希未加盐,则很容易知道其他密码。
    【解决方案5】:

    bycrpt 的意义在于 占用处理器! (相对而言。)正是由于这个原因,密码散列比 SHA1/2 “更好”。 (这个“更好”假设密码哈希已经在攻击者手中或以其他方式暴露;虽然如果不是这样就好了,即使是大公司也有安全隐患。)

    bcrypt 明确考虑了此要求——如果您每秒只能处理 1k 哈希(不过,这是一个很好的登录尝试),这需要多长时间攻击者暴力破解?比他们每秒处理 1000 万个哈希值要长得多!暴力破解的目标攻击空间仅是允许的密码输入,通常要小得多——尤其是。在实践中使用“简单密码”——而不是散列空间!

    并且非常需要盐来避免以时间换空间的彩虹表 :) 实际上需要为每个独特的盐值创建彩虹表。(因此,更独特的盐值,需要更多的空间,如果值足够,这对于攻击者来说变得不切实际。)

    编码愉快。

    【讨论】:

    • 我了解 bcrypt 的实用性,并且可以很容易地证明它适用于桌面应用程序。但是,我正在创建的 Web 应用程序可能会被同一共享服务器上的许多不同客户使用。处理器利用率过高往往会使主机脾气暴躁。它究竟有多密集?它在我正在编写的那种应用程序中有实用程序吗?
    • @Matty 我不知道 PHP 的实现/包装器,但 bcrypt 旨在通过性能“增长”。可以为某个cost配置,其中轮数为6^cost。至于它将如何在某个服务器/负载上运行需要测试。总体而言,在大多数情况下,散列密码是一种廉价且不频繁的操作——还有很多其他的东西首先会成为瓶颈。
    • 在这种情况下,我可能不得不回避bcrypt :-(
    • @Matty 为什么?您是否运行过性能分析说“太慢了”?一个操作的总成本cost * count。对于非常小的 count,任何相当小的 cost 都会被边缘化掉。
    • @Matty ... 首先会有其他问题 :) 就像,你知道的,运行 PHP。这是一种非常糟糕的过早优化。
    猜你喜欢
    • 2022-12-04
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2020-12-31
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多