在关于哈希和盐析密码的教程中,我看到使用for循环多次执行hash + salt。
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
使用这种方法有什么好处?它是否更安全,例如蛮力方法? 另外:我应该考虑除sha256之外的其他哈希算法吗?我知道没有明确的答案,因为它可能取决于许多因素,如安全程度,速度等。但是有没有建议让我们说一个相当简单的网站?
答案 0 :(得分:3)
多次迭代散列的原因是减慢计算速度。今天(2013年),您可以使用通用硬件计算每秒1.4 Giga SHA256 hashes,因此您可以在几分之一毫秒内强制使用大约500,000个单词的整个英语词典。
这就是为什么人们应该使用像BCrypt或PBKDF2这样的慢速密钥派生函数来散列密码。使用几毫秒进行登录是没有问题的,但是每秒只有1000个单词的强制执行是不切实际的。
PHP 5.5将自己的函数password_hash()和password_verify()准备好,以简化生成BCrypt哈希值。我强烈建议使用这个优秀的api,或者compatibility pack用于早期的PHP版本。用法非常简单:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
如果您对更详细的答案感兴趣,可以查看我的tutorial关于安全存储密码的信息。
答案 1 :(得分:1)
http://www.openwall.com/phpass/
是一个比较好用的解决方案,我会考虑实现它。
存在这样的循环的原因是减慢散列过程。 Revese查找表需要更长时间,因为有更多的计算。
通过在那里进行循环,您已经减慢了扫描密码的人数达65536次。