PHP password_hash() 函数使用强大的单向哈希算法创建密码哈希。它与 crypt() 兼容。因此,由 crypt() 创建的密码哈希可以与此函数一起使用。
以下算法是目前支持:
- PASSWORD_DEFAULT - 从 PHP 5.5.0 开始默认使用 BCRYPT 算法。请注意,随着新的和更强大的算法被添加到 PHP 中,此常量可能会随着时间的推移而改变,因此允许存储扩展到超过 60 个字符(建议 255 个)。
- PASSWORD_BCRYPT - 使用 CRYPT_BLOWFISH创建哈希的算法。这将使用"$2y$"标识符生成标准的 crypt() 兼容哈希值。结果始终是 60 个字符的字符串,失败时返回 false。
- PASSWORD_ARGON2I - 使用 Argon2i 哈希算法创建哈希。仅当 PHP 编译时支持 Argon2 时,此算法才可用。
- PASSWORD_ARGON2ID - 使用 Argon2id 哈希算法创建哈希。仅当 PHP 编译时支持 Argon2 时,此算法才可用。
PASSWORD_BCRYPT 支持的选项:
salt(字符串)- 手动提供在散列密码时使用的盐。这将覆盖并阻止自动生成盐。
如果省略,password_hash()将为每个散列的密码生成随机盐。这是预期的操作模式,从 PHP 7.0.0 开始,salt 选项已被弃用。
cost (int) - 表示应使用的算法成本。
如果省略,将使用默认值 10。这是一个不错的基准成本,但您可能需要考虑根据您的硬件增加它。
PASSWORD_ARGON2I 和 支持的选项PASSWORD_ARGON2ID:
- memory_cost (int) - 可用于计算 Argon2 哈希值的最大内存(以字节为单位)。默认值为 PASSWORD_ARGON2_DEFAULT_MEMORY_COST。
- time_cost (int) - 计算 Argon2 哈希所需的最长时间。默认值为 PASSWORD_ARGON2_DEFAULT_TIME_COST。
- threads (int) - 用于计算 Argon2 哈希值的线程数。默认值为 PASSWORD_ARGON2_DEFAULT_THREADS。仅适用于 libargon2,不适用于 libsodium 实现。
语法
password_hash(password, algo, options)
参数
passwrod |
|
algo | 必填。 指定密码算法常量,表示对密码进行哈希处理时使用的算法。 |
options |
|
返回值
返回哈希密码。
使用的算法、成本和盐作为哈希的一部分返回。因此,验证哈希所需的所有信息都包含在其中。这允许 password_verify() 函数验证哈希值,而无需单独存储盐或算法信息。
示例:password_hash()示例
下面的示例显示了password_hash()函数的用法。
<?php
//使用当前默认值对密码进行哈希处理
//目前是BCRYPT的算法,以及
//产生 60 个字符的结果。请注意,默认值
//可能会随着时间的推移而改变,因此允许存储
//扩展过去60个字符(推荐255个)
echo password_hash("myPassword", PASSWORD_DEFAULT);
?>
上述代码的输出将是类似于:
$2y$10$Hm6KC1/82.P4Nq.BxTRHt.2W38QueusDaa6rCvO5KhP79RyDyXq7C
示例:手动设置cost
在下面的示例中,手动设置 BCRYPT 算法的成本。
<?php
//将BCRYPT的默认成本增加到11
$options = array('cost' => 11);
//使用BCRYPT算法对密码进行哈希处理
echo password_hash("myPassword", PASSWORD_BCRYPT, $options);
?>
上述代码的输出将类似于:
$2y$11$qy1hDCTAxJ7WL7pZn0H4Le6oWEgo63nTGzrpxSCpP3MK1yJzc/O1G
示例:找到一个好的成本
下面的示例解释了如何为 BCRYPT 哈希算法找到一个好的成本.
<?php
//下面的代码将对服务器进行基准测试以确定
//在不减慢速度的情况下可以承受多高的成本
//太多了。 8-10 是一个很好的基线,越多越好
//如果服务器足够快。下面的代码旨在
//对于≤50毫秒的拉伸时间,这是一个很好的
//系统处理交互式登录的基线
$timeTarget = 0.05; // 50 毫秒
$cost = 8;
do {
$cost++;
$start = microtime(true);
password_hash("myPassword", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
echo "Appropriate Cost Found: " . $cost;
?>
上述代码的输出将类似于:
Appropriate Cost Found: 10
示例:使用 Argon2i
再考虑一个使用 ARGON2I 散列的示例算法用于创建哈希。
<?php
//使用ARGON2I算法对密码进行哈希处理
echo "Argon2i hash: \n";
echo password_hash('myPassword', PASSWORD_ARGON2I);
?>
上述代码的输出将类似于(为了便于阅读而自动换行):
Argon2i hash:
$argon2i$v=19$m=65536,t=4,p=1$ZUl3S2V6LnJBWS5EM1FybQ$E
fVOU5v98/oM1EExvYUM0mFcWUHZ+QrWLqsohVvuixs
注意:建议在您的服务器上测试此功能,并调整成本参数,使该功能在交互式系统上的执行时间少于100毫秒。