2

在关于散列和加盐密码的教程中,我看到使用 for 循环多次执行散列+盐。

    $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 之外的另一种散列算法吗?我知道没有明确的答案,因为它可能取决于许多因素,例如安全程度、速度等。但是对于一个相当简单的网站有什么建议吗?

4

2 回答 2

3

多次迭代散列的原因是为了减慢计算速度。今天(2013 年),您可以使用通用硬件每秒计算约1.4 Giga SHA256 哈希值,因此您可以在不到一毫秒的时间内暴力破解包含约 500,000 个单词的整个英语词典。

这就是为什么人们应该使用像 BCrypt 或 PBKDF2 这样的慢速密钥派生函数来散列密码。使用几毫秒进行登录是没有问题的,但是每秒仅 1000 个单词的暴力破解是不切实际的。

PHP 5.5 将有自己的函数password_hash()和 password_verify() 准备好,以简化生成 BCrypt 哈希。我强烈推荐使用这个优秀的 api,或者它是早期 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);

如果您对更详细的答案感兴趣,可以查看我关于安全存储密码的教程。

于 2013-06-19T20:33:31.600 回答
1

http://www.openwall.com/phpass/

是更常用的解决方案之一,我会考虑实现它。

存在这样的循环的原因是减慢散列过程。修改查找表需要更长的时间,因为有更多的计算。

通过在那里进行循环,您可以将某人扫描密码的速度减慢多达 65536 次。

于 2013-06-19T18:35:38.673 回答