2013 年的密码哈希

2022-01-22 00:00:00 hash passwords php pbkdf2

当今这些最佳"解决方案是什么?

What is the "best" solution these today?

这似乎是一个不错的选择:https://defuse.ca/php-pbkdf2.htm

This seems a good option: https://defuse.ca/php-pbkdf2.htm

但是升级到 PHP5.5 并使用它怎么样?http://php.net/manual/en/function.hash-pbkdf2.php

But then how about upgrading to PHP5.5 and using this? http://php.net/manual/en/function.hash-pbkdf2.php

很好奇为什么 PHP 网站声明:

Curious as to why the PHP site states:

注意PBKDF2 方法可用于存储密码的散列(NIST 批准用于该用途).不过需要注意的是,CRYPT_BLOWFISH 更适合密码存储,应该通过 crypt() 来代替.

Caution The PBKDF2 method can be used for hashing passwords for storage (it is NIST approved for that use). However, it should be noted that CRYPT_BLOWFISH is better suited for password storage and should be used instead via crypt().

对于低于 5.5 的 PHP 版本,使用 defuse.ca 解决方案是否公平,然后在升级到 PHP5.5 后将其切换出来?

For PHP versions less that 5.5 would it be fair to use the defuse.ca solution, and then just switch it out after upgrading to PHP5.5?

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}

这是来自 defuse.ca 的当前解决方案,将这个函数重命名为 hash_pbkdf2() 是否公平,并且在升级到 PHP5.5 后过渡会很顺利?

This is the current solution from defuse.ca, would it be fair to rename this function to hash_pbkdf2() and after upgrading to PHP5.5 transition would be nice and smooth?

推荐答案

从 PHP 5.5 开始,公认的 PHP 密码最佳实践是 password_hash.它提供了一种单一、统一、内置、未来兼容的方式来生成安全密码哈希.

The accepted best practice in PHP passwords, as of PHP 5.5, is password_hash. It presents a single, unified, built-in, future-compatible way to generate a secure password hash.

如果您使用的是 5.3.x 或更高版本的安全更新版本,则可以使用 password_compat 库 代替.

If you are using a security-updated version of 5.3.x or higher, you can use the password_compat library instead.

在幕后,当前版本使用一些预定义的安全性调用 crypt选项.未来版本可能会更改默认选项.

Under the covers, the current version makes calls to crypt with some predefined security options. Future versions may change the default options.

请务必仔细阅读 crypt 页面上讨论 CRYPT_BLOWFISH 版本控制的部分,并查看 password_compat 页面上的版本控制说明.

Please be sure to carefully read the section on the crypt page that talks about CRYPT_BLOWFISH versioning, as well as review the versioning notes on the password_compat page.

正如警告消息中明确指出的,PBKDF2 被 NIST 接受为存储密码的适当方式.您可以使用它的实现而不用担心,但只有在需要支持 5.3 之前的 PHP 版本或需要支持 CRYPT_BLOWFISH<损坏的 PHP 版本时才应该这样做/代码>.

As noted clearly in the warning message, PBKDF2 is accepted by the NIST as an adequate way to store passwords. You can use implementations of it without significant concern, but you should only do so if you either need support for PHP versions prior to 5.3, or need to support PHP versions that have a broken CRYPT_BLOWFISH.

相关文章