【问题标题】:Password Hashing, BCrypt to SHA1/MD5密码散列,BCrypt 到 SHA1/MD5
【发布时间】:2013-04-24 06:51:34
【问题描述】:

我一直在考虑升级我的一个应用程序的密码哈希安全性,因为我一直在阅读关于蛮力攻击比以前快得多的信息。目前我正在使用sha1(md5($password)),我看到了使用 bcrypt + salt 的好处。我的问题是,如果我执行以下操作会更安全吗:

场景 1:

$password -> sha1 -> bcrypt -> sha1
// This would enable me to keep all existing passwords and just 
// regenerate all the hashes without waiting for the user to re login

场景 2:

$password -> bcrypt -> sha1
// I would have to add an extra column for the new hash until every
// user has logged in but the hash will still be sha1.

这两者中的任何一个都会增加哈希的安全性吗?我不是密码学大师,远非如此,我只想简单解释一下它是否可行,如果不可行,以及为什么。

谢谢

编辑

再读一读后,似乎 bcrypt 受到青睐,因为它的缓慢性在于 i 使 cpu/gpu 在生成哈希之前工作更长时间。

在 sha1 与 bcrypt 的情况下,sha1 大约比 bcrypt 快 300000 倍。这就引出了一个问题,如果 bcrypts 的优势是速度慢,那么使用 sha1 300000 次的递归散列函数肯定会和 bcrypt 一样安全吗?

我以这个函数为例:

function bsha1($data, $salt) {

$hash = $data;

for ($i = 0; $i < 300000; ++$i) {

$hash = sha1($hash . $salt);

}

为它提供一个盐,它会返回一个 sha1 散列,其中每次迭代都是一个散列散列和盐。这需要与 bcrypt 大致相同的时间。这会一样安全吗?

【问题讨论】:

  • 最好不要在密码之前播种和加盐,例如:md5(md5(uniqueid/seed).my5(password).md5(now()).md5(seed)) 在一天结束时,所有这些都在您的建议中,您只是在进行链式加密。并且 sha1 很容易被破坏 tbh (因为 md5 我只是将其用作示例)在密码生成上实现随机性是最好的我使用注册日期 + 每个用户的种子密钥 + 唯一用户 ID 将它们全部链接在一起在多次传球中,然后是一次主传球。它仍在链接加密,但例如“密码”变为“1230982348762密码89134598712390874”,因此长度增加
  • @Dave:请不要建议自己滚动。自己滚会让你一个人呆着。取而代之的是社区认为有效的东西,这不会让你孤单,以防万一研究发现某些部分有缺陷甚至损坏。
  • 它并不完全是你自己的,它基本上完全按照罗伯特的建议做。另外仅供参考,上面的示例正是它在 vbulletin 中的完成方式。
  • @Ozzy - 不能说 SHA-1 比 BCrypt 快 x 倍,因为 BCrypt 散列一个成本因素,它决定了必要的时间。这个成本因素是重要的一点。你用迭代做的事情是相似的,但 BCrypt 做得更好。例如,它在每次迭代中重用盐和原始密码,并且它以使用更多内存的方式构建,以使 GPU 更难暴力破解。
  • @Dave - 在您的示例中,您使用了 MD5 5 次(是的,我知道这只是一个示例,但是一个很好的示例......)。使用这个算法,我们可以每秒计算超过 1 Giga 的哈希值,这意味着在几分之一毫秒内就可以计算出完整的英文字典......使用 BCrypt 你不能这样做,一个有意义的值是每毫秒 1 个哈希值,那么为什么不使用它(?),它更容易申请。

标签: php encryption hash sha1 bcrypt


【解决方案1】:

你最好升级到password_hash()

由于您可能还没有使用 PHP 5.5(我假设您此时可能已经用于测试目的),您可以使用 PHP userland implementation of password_hash() also written by Ircmaxell for PHP 5.3+

要在登录时升级密码哈希,您从数据库中获取哈希并首先针对新的哈希进行测试。如果它返回 FALSE,您将针对旧的散列进行测试。如果返回 TRUE,则使用新的新哈希重新对密码进行哈希处理并将其存储回数据库中。

相互组合或链接多个哈希 - 我担心我在你的问题中读到过 - 是你永远不应该考虑的完全愚蠢的事情。散列算法彼此不兼容,并且以这种方式在散列上使用散列是错误的:sha1(md5($password)) 等有效地减少了输出空间,从而更容易受到攻击——这是你将来想要防止的。

因此,使用 PHP 中的新密码哈希 API 并睡个好觉。

【讨论】:

  • 在这种特殊情况下,您甚至可以使用 '$2y$' 测试哈希值的开头,因此如果哈希是使用 BCrypt 生成的,您现在可以立即测试。
  • @martinstoeckli:我很确定 password_hash API 已经为您完成了这项工作,所以是和否 :)
  • 我不完全同意“减少输出空间”的推理,但除此之外这绝对是最好的答案。
  • @PeterElliott:针对 MD5 平原的暴力破解 SHA 有效。 SHA越多越好,例如SHA2、SHA3。 SHA* 的输出位总是比 MD5 提供的输入位多。这也有效地减少了输出位,因为与哈希最初设计的理论上不受限制的输入集相比,现在有一组有限的输入值。
  • @M8R-1jmw5r - 只有使用crypt()(API 内部使用)创建的散列值包含此“标头”。如果直接调用sha1(),API 没有机会识别使用的算法。这就是为什么我写“在这种特殊情况下”,旧的哈希值不包含标题,但 OP 知道使用了什么算法。
【解决方案2】:

这两种情况都没有比 bcrypt 提供更多的安全余量。也就是说,bcrypt 绝对是一种可以抵抗暴力破解的散列算法,因为它具有足够高的成本因素,它需要比任何基于 SHA 的散列方案更长的时间来散列。

话虽如此,场景 1 可能是要走的路,因为您现在可以保护您的数据库,而不是在用户登录时零敲碎打。尽管 M8R-1jmw5r 在他/她的回答中说了什么,但结合散列算法并没有不会为您提供任何额外的安全性,但也不会真正对您的安全性产生负面影响。

【讨论】:

    【解决方案3】:

    您可以使用任何标准散列算法,但作为标准散列函数,它们可以回溯,存在潜在的安全风险。

    您最好使用任何散列函数,但将其与盐与您的个人密钥结合使用。这是链接

    http://www.php.net/manual/en/faq.passwords.php#faq.passwords.fasthash

    【讨论】:

    • 不,您最好使用专用于密码散列的散列函数。
    • 是的,但是盐会增加一些额外的安全性@M8R-1jmw5r
    • 没有额外的安全性。每当您选择主题时(您应该不时这样做),然后您需要了解最新技术,而不是放弃behing。安全是一个过程,其中一部分是保持最新状态。最好建议一个专用于 PHP 中的密码散列的 API,即使它已经在 PHP 3/4 中正常工作。那是很久以前的事了。
    【解决方案4】:

    简短的回答是肯定的,这会有所帮助。然而,长答案是否定的,因为 SHA-1 和 MD5 现在只是弱散列算法。最好只使用 SHA-2 算法,或者等待更长时间并直接使用 SHA-3。

    问题在于哈希函数。三层肯定会阻止某人,但老实说大多数时候一层足以让大多数人甚至不打扰。如果有人非常想进入,我至少会使用 SHA-2,否则你应该对你拥有的东西没问题。

    编辑::

    好吧,澄清一下。将 SHA1 与 Bcrypt 一起使用并不是最好的方法。我会使用带有 bcrypt 的 SHA-2 算法,这将比使用 SHA-1 更安全。另外,层我的意思是 Bcrypt 是一个哈希传递,SHA-1 是一个哈希传递,第二个 SHA-1 是另一个哈希传递。我真的不明白为什么这是错误的?抱歉,关于图层的语义存在差异。

    EDIT2::

    $Password -&gt; Bcrypt -&gt; SHA-2Bcrypt(SHA-2($Password)) 其中SHA-2 是 SHA-2 系列哈希算法之一。

    使用 SHA-2 而不是 SHA-1 的代码比 Bcrypt 更清晰。

    【讨论】:

    • bcrypt 不是“弱散列函数”,建议某人在密码散列方案中使用 SHA2 是个坏主意
    • @PeterElliott MD5 和 SHA-1 绝对是弱散列算法。这就是为什么它们不再用于 SHA-2 标准,现在将成为 SHA-3。那么我到底错在哪里?另外,到底为什么使用 SHA-2 是个坏主意?你知道有人拥有可以破解哈希的超级计算机吗?但是,我有一台能够同时破解 MD5 和 SHA-1 的计算机。
    • @Nomad101:你错了,因为这不是当今如何进行密码散列的已知方法。另外我想知道您是否真的理解 OP 的要求,因此答案可能会误导您说 “散列哈希会有所帮助”。我敢打赌你不这么认为,但是你的答案可以这样解读。
    • @Nomad101:您在回答中使用术语 Layer 是什么意思?在 SHA-* 哈希系列所属的加密哈希领域中,我找不到任何明确的参考。正如您可能知道的那样,您可以暴力破解任何哈希,这里的费用很有趣。您正在建议旨在快速工作的散列算法。这与您尝试实现的密码哈希相反。
    • SHA-2 速度太快,无法在密码哈希方案中使用,因为比特币(本质上围绕暴力破解 SHA256)意味着大量研究正在投入到以同样快的速度执行 SHA256尽可能。散列算法的设计目的并不是像 bcrypt 那样保证密码安全,很明显你不知道它们应该如何工作。
    猜你喜欢
    • 1970-01-01
    • 2021-07-03
    • 2019-06-23
    • 2015-05-03
    • 2011-06-08
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    相关资源
    最近更新 更多