【发布时间】: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