在 PHP 5.5 中生成密码哈希并设置成本选项

2022-08-30 22:21:23

我知道PHP 5.5处于alpha阶段,但是我正在制作的这个类只是提前制作的,以通过使用function_exists()来利用它的哈希功能。

我查看了password_hash文档。第三个参数是针对$options目前支持两个选项,“盐”和“成本”。

它声明如下:

cost,表示应使用的算法成本。这些值的示例可以在 crypt() 页面上找到。

当我进入crypt()页面时,它给出的文档是:

河豚用盐散列如下:“$2a$”,“$2x$”或“$2y$”,两位数的成本参数“$”和字母表中的22位数字“./0-9A-Za-z”。在 salt 中使用此范围之外的字符将导致 crypt() 返回长度为零的字符串。两位数成本参数是基于 Blowfish 的底层哈希算法生成器的迭代计数的 base-2 对数,并且必须在 04-31 范围内,超出此范围的值将导致 crypt() 失败。5.3.7 之前的 PHP 版本仅支持“$2a$”作为 salt 前缀:PHP 5.3.7 引入了新的前缀来修复 Blowfish 实现中的安全漏洞。有关安全修复的完整详细信息,请参阅»本文档,但总而言之,仅针对PHP 5.3.7及更高版本的开发人员应使用“$2y$”而不是“$2a$”。

我似乎无法将我的头缠绕在这件事上。它说PHP 5.3.7及更高版本应该使用$ 2y $,但是我用什么成本值来获得那个,它是选择的最佳价值吗?他们提供的示例使用值7,但根据上面的值,它可以上升到31,使用说4而不是说31有什么区别?


答案 1

该函数只是函数的包装器,并且应该更容易正确使用它。它负责生成安全的随机盐,并提供良好的默认值。password_hash()crypt()

使用此函数的最简单方法是:

$hash = password_hash($password, PASSWORD_DEFAULT);

这意味着,该函数将使用BCrypt(算法)对密码进行哈希处理,生成随机盐,并使用默认成本(目前为10)。这些都是很好的默认值,特别是我不建议生成自己的盐,很容易在那里犯错误。2y

如果要更改成本参数,可以按如下方式操作:

$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 11]);

将成本参数增加 1,将使计算哈希值所需的时间加倍。成本参数是迭代计数的对数(以 2 为底),这意味着:

$iterations = 2 ^ $cost;

编辑:

我错过了一点,你想生成自己的类。对于 PHP 版本 5.3.7 及更高版本,存在一个兼容包,该兼容包来自创建该函数的同一作者。您可以直接使用此代码,也可以查看精心设计的实现。对于 5.3.7 之前的 PHP 版本,不支持 with ,unicode 感知 BCrypt 算法。您可以改用 ,这是早期 PHP 版本的最佳替代方案。我做了一个有很多评论的例子,也许你也想看看它。password_hash()crypt2y2a

附言:表达式“salt”和“cost factor”在crypt()函数中使用正确,尽管将所有crypt参数一起使用“salt”一词,这有点误导。password_hash()


答案 2

免责声明:这是PHP 5.3.10,但它似乎与您的描述没有什么不同。

成本适用于计算成本。增加成本值时,对密码进行哈希处理需要更长的时间

function blowfish_salt($cost)
{
    $chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt = sprintf('$2y$%02d$', $cost);
    for ($i = 0; $i < 22; ++$i)
        $salt .= $chars[rand(0,63)];

    return $salt;
}

$password = 'My perfect password';
$cost = $argv[1];
$salt = blowfish_salt($cost);
$hash = crypt($password, $salt);

当我在我的(旧)机器上运行它时

php mycrypt.php 10

它立即返回(约0.2秒),而

php mycrypt.php 16

大约需要5.2秒。


推荐