密码散列算法
PHP 提供了 password_hash() 和 password_verify() 函数,用于安全地存储和验证用户密码。这两个函数内置了盐值生成、算法选择和自适应成本因子,是 PHP 中密码存储的最佳实践。
password_hash
php
<?php
declare(strict_types=1);
// 对密码进行哈希
$password = 'MySecurePassword123!';
$hash = password_hash($password, PASSWORD_BCRYPT);
echo "哈希值: {$hash}" . PHP_EOL;
// 输出类似: $2y$10$N9qo8uLOickgx2ZMRZoMy...算法常量
php
<?php
declare(strict_types=1);
// PASSWORD_BCRYPT - bcrypt 算法(默认)
$hash = password_hash($password, PASSWORD_BCRYPT);
// PASSWORD_ARGON2ID - Argon2id 算法(PHP 7.3+,推荐)
$hash = password_hash($password, PASSWORD_ARGON2ID);
// PASSWORD_ARGON2I - Argon2i 算法(PHP 7.3+)
$hash = password_hash($password, PASSWORD_ARGON2I);
// PASSWORD_DEFAULT - 默认算法(随 PHP 版本变化)
$hash = password_hash($password, PASSWORD_DEFAULT);自定义选项
php
<?php
declare(strict_types=1);
// Bcrypt 选项
$options = [
'cost' => 12, // 成本因子(4~31,越高越安全但越慢)
];
$hash = password_hash($password, PASSWORD_BCRYPT, $options);
// Argon2id 选项
$options = [
'memory_cost' => 65536, // 内存成本(KB),默认 65536
'time_cost' => 4, // 时间成本,默认 4
'threads' => 1, // 并行线程数,默认 1
];
$hash = password_hash($password, PASSWORD_ARGON2ID, $options);password_verify
php
<?php
declare(strict_types=1);
// 用户登录验证
function verifyLogin(string $inputPassword, string $storedHash): bool
{
return password_verify($inputPassword, $storedHash);
}
// 使用示例
$storedHash = '$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy';
if (verifyLogin('MySecurePassword123!', $storedHash)) {
echo "登录成功" . PHP_EOL;
} else {
echo "密码错误" . PHP_EOL;
}password_needs_rehash
php
<?php
declare(strict_types=1);
// 检查是否需要更新哈希(当算法或成本因子变化时)
function checkAndRehash(string $password, string $hash): ?string
{
if (password_needs_rehash($hash, PASSWORD_ARGON2ID)) {
echo "密码哈希需要更新" . PHP_EOL;
return password_hash($password, PASSWORD_ARGON2ID);
}
return null;
}
// 使用示例
// $user->password_hash = checkAndRehash($inputPassword, $user->password_hash);注意事项
- 永远不要自己实现密码哈希,使用
password_hash() - 不要使用 MD5/SHA1 存储密码
- cost 参数越高越安全,但会增加计算时间
- 使用 password_needs_rehash 在登录时更新哈希
下一节
继续学习:DateTime 类