循环hmac哈希是否有用?

时间:2012-06-20 15:55:51

标签: php security hmac

我需要在数据库中存储密码,并且我曾经将盐渍密码的sha1哈希与随机盐一起存储,这是循环的,如下所示:

$salt = sha1(microtime().mt_rand());
for ($i=0; $i < 4000; $i++) {
    $password = sha1($password.$salt);
}

(在我的示例中,$password$salt存储在数据库中。)

我最近发现了hash_hmac()函数,它显然比简单的SHA1哈希更安全。我计划使用相同的模式(盐是密钥),但我想知道是否值得循环它像我之前的例子。如果有人能给我一些见解,那就非常感激了。

1 个答案:

答案 0 :(得分:2)

您在此处所做的工作称为 key stretching ,它将攻击者必须采取的时间乘以检查每个候选密码与哈希值。在您的示例中,它将时间增加了4000倍。你在这里要防范的具体威胁是攻击者掌握你的哈希值(比如LinkedIn,Last.fm和eHarmony最近发生的事情)并且可以投入尽可能多的CPU能力来破解它们。

如果这不是研究项目,那么您应该使用一个众所周知且经过公开测试的功能,例如bcrypt()PBKDF2()scrypt(),而不是自己动手。 / p>

该循环中的数字应远远高于4000,并且由于攻击者将使用C循环而不是PHP循环,因此您将无法在合理的时间内完成尽可能多的操作。即使在PHP循环中,我也可以在0.3秒内完成500,000次。上面的散列算法解决了这个问题,因为它们将在C中实现。(Not all of them may be available in PHP。)似乎bcrypt在5.3中,但它被称为CRYPT_BLOWFISHDetails on how to use it are on the crypt() page


hash_hmac()不是更安全的散列算法,而是用于其他目的。见the end of Thomas' answer here。像MD5SHA系列这样的算法是通用散列算法,通常用作特定用途的更具体算法的一部分。例如,上述一些密码散列算法多次使用通用散列算法。 has_hmac()询问您要使用哪种通用哈希算法。