在现代 Web 应用开发中,用户密码的安全存储至关重要。PHP 内置的 crypt() 函数支持多种加密算法,其中就包括 Blowfish 加密算法。Blowfish 算法以其高强度和可定制的工作因子(cost)被广泛用于密码哈希。本文将详细介绍如何利用 PHP 的 crypt() 函数使用 Blowfish 算法(标识符为 $2y$)对密码进行安全加密。
Blowfish 是一种对称密钥加密算法,专门设计用于替代较旧的加密算法。针对密码哈希,Blowfish 以其可调节的“工作因子”提供了良好的防暴力破解能力,工作因子越高,计算加密所需时间越长,从而提高密码安全性。
PHP 的 crypt() 函数使用 $2y$ 标识符表示 Blowfish 哈希格式,这是 PHP 5.3.7 及以上版本推荐使用的格式,能避免早期版本的安全问题。
Blowfish 算法的盐是一个 22 字符的字符串,包含 a-z, A-Z, 0-9, ., / 共 64 个字符。PHP 的 crypt() 要求盐格式如下:
$2y$ + 两位工作因子(cost) + $ + 22 位盐
例如:
$salt = '$2y$12$' . substr(strtr(base64_encode(random_bytes(16)), '+', '.'), 0, 22);
这里,12 是工作因子,代表 2^12 次哈希计算,约等于 4096 次,既安全又不会太慢。
$password = 'your_password_here';
$hash = crypt($password, $salt);
返回的 $hash 是一个完整的 Blowfish 哈希字符串,可以直接存入数据库。
验证密码时,直接使用原哈希作为盐调用 crypt(),比较结果即可:
function verify_password($password, $hash) {
return crypt($password, $hash) === $hash;
}
<?php
// 生成安全盐
function generate_blowfish_salt($cost = 12) {
if ($cost < 4 || $cost > 31) {
throw new InvalidArgumentException("工作因子必须在4到31之间");
}
$randomBytes = random_bytes(16);
$base64Salt = substr(strtr(base64_encode($randomBytes), '+', '.'), 0, 22);
return sprintf('$2y$%02d$%s', $cost, $base64Salt);
}
// 加密密码
function encrypt_password($password, $cost = 12) {
$salt = generate_blowfish_salt($cost);
return crypt($password, $salt);
}
// 验证密码
function verify_password($password, $hash) {
return crypt($password, $hash) === $hash;
}
// 测试
$password = 'mypassword123';
$hash = encrypt_password($password);
echo "密码哈希: $hash\n";
if (verify_password('mypassword123', $hash)) {
echo "密码验证成功!\n";
} else {
echo "密码验证失败!\n";
}
?>