密码哈希,BCrypt到SHA1 / MD5

时间:2013-04-30 11:08:28

标签: php encryption hash sha1 bcrypt

我一直在考虑升级我的某个应用程序的密码哈希安全性,因为我一直在阅读有关暴力攻击的速度比以前快得多。目前我正在使用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受到青睐,因为它的生长缓慢,因为我在生成哈希之前使cpu / gpu的工作时间更长。

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

我以此功能为例:

function bsha1($data, $salt) {

$hash = $data;

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

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

}

为它提供一个salt,它会返回一个sha1哈希,其中每次迭代都是哈希哈希和盐。这与bcrypt大致相同。这会安全吗?

4 个答案:

答案 0 :(得分:11)

您最好升级到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,并且能够很好地睡眠。

答案 1 :(得分:0)

这两种方案都没有比bcrypt更多的安全边际。也就是说,bcrypt绝对是一种可以抵抗暴力强制的散列算法的方法,因为足够高的成本因子,哈希比任何基于SHA的散列方案需要更长的时间。

说了所有这些,方案1可能是要走的路,因为你现在可以保护你的数据库而不是用户登录时的零碎。尽管M8R-1jmw5r在他/她的回答中说,结合散列算法并没有为您提供额外的安全性,但它也不会对您的安全产生负面影响。

答案 2 :(得分:-2)

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

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

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

答案 3 :(得分:-3)

简短的回答是肯定会有所帮助。然而,长期的答案是否定的,因为SHA-1和MD5现在只是弱哈希算法。你最好使用SHA-2算法,甚至再等一会儿,直接进入SHA-3。

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

编辑::

好的,以澄清上述内容。将SHA1与Bcrypt一起使用并不是最好的方法。我会使用带有bcrypt的SHA-2算法,这会比使用SHA-1更安全。同样通过层我的意思是Bcrypt是一个Hash传递SHA-1是一个Hash传递,第二个SHA-1是另一个Hash传递。我真的不明白为什么这是错的?很抱歉有关图层的语义差异。

EDIT2 ::

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

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