我需要在数据库中存储密码,并且我曾经将盐渍密码的sha1哈希与随机盐一起存储,这是循环的,如下所示:
$salt = sha1(microtime().mt_rand());
for ($i=0; $i < 4000; $i++) {
$password = sha1($password.$salt);
}
(在我的示例中,$password
和$salt
存储在数据库中。)
我最近发现了hash_hmac()
函数,它显然比简单的SHA1哈希更安全。我计划使用相同的模式(盐是密钥),但我想知道是否值得循环它像我之前的例子。如果有人能给我一些见解,那就非常感激了。
答案 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_BLOWFISH
。 Details on how to use it are on the crypt() page
hash_hmac()
不是更安全的散列算法,而是用于其他目的。见the end of Thomas' answer here。像MD5
和SHA
系列这样的算法是通用散列算法,通常用作特定用途的更具体算法的一部分。例如,上述一些密码散列算法多次使用通用散列算法。 has_hmac()
询问您要使用哪种通用哈希算法。