【问题标题】:Hashing salting being performed multiple times多次执行哈希加盐
【发布时间】:2013-06-19 18:29:54
【问题描述】:

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

【问题讨论】:

    标签: hash passwords salt


    【解决方案1】:

    多次迭代散列的原因是为了减慢计算速度。今天(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 关于安全存储密码的信息。

    【讨论】:

    • 非常感谢您的详尽回答。您的教程非常适合像我这样的散列和加盐密码领域的初学者。
    【解决方案2】:

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

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

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

    通过该循环,您可以将某人扫描密码的速度降低多达 65536 倍。

    【讨论】:

      猜你喜欢
      • 2011-05-27
      • 2012-11-04
      • 2011-12-06
      • 1970-01-01
      • 2016-09-17
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多