2012-06-20 41 views
0

我需要在数据库中存储的密码,我用来存放腌密码的SHA1哈希旁边一个随机盐,这是循环,就像这样:循环hmac散列是否有用?

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

(在我的例子,$password和在db里面存储了$salt)。

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

回答

2

是的。

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

如果这不是一个研究项目,而应该使用一个众所周知的公开测试函数,如bcrypt(),PBKDF2()scrypt()

该循环中的数字应该远高于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()问你想使用哪种通用哈希算法。