2012-06-20 88 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()問你想使用哪種通用哈希算法。