PHP不可逆加密算法详解

```html PHP不可逆加密算法详解

PHP不可逆加密算法详解

在Web开发中,“不可逆加密”实为密码哈希(Password Hashing)——即单向散列,无法还原明文,但可安全验证用户密码。PHP 提供了原生、安全、推荐的 password_hash()password_verify() 函数,彻底取代了过时的 md5()sha1() 等不安全方案。

✅ 为什么不能用 md5() 或 sha1()?

这些算法计算快、无盐值(salt)、易受彩虹表攻击。即使加盐,手动实现也极易出错。PHP 7.4+ 已弃用 crypt() 的弱算法支持,务必使用现代密码哈希方案

✅ 推荐方案:Argon2i / bcrypt(PHP 7.2+)

PHP 默认使用 bcrypt(兼容性好),若启用了 libsodium 扩展,还可选用更抗侧信道攻击的 Argon2i

// ✅ 安全哈希:自动加盐 + 自适应成本因子
$plainPassword = "MyP@ssw0rd!2024";
$hash = password_hash($plainPassword, PASSWORD_ARGON2I, [
    'memory_cost' => 65536, // 64MB 内存
    'time_cost'   => 4,     // 迭代次数
    'threads'     => 2      // 并行线程数
]);

echo "哈希结果:$hash\n";
// 输出示例:$argon2i$v=19$m=65536,t=4,p=2$...$...

若未启用 Argon2,可退而使用 bcrypt(PHP 5.5+ 全版本支持):

// ✅ 兼容性强的 bcrypt 方案
$hash = password_hash($plainPassword, PASSWORD_BCRYPT, [
    'cost' => 12 // 成本因子(2^12 ≈ 4096 次迭代)
]);

✅ 验证密码:永远用 password_verify()

// 用户登录时验证
$inputPassword = $_POST['password'] ?? '';
if (password_verify($inputPassword, $hash)) {
    echo "✅ 密码正确!";
} else {
    echo "❌ 密码错误。";
}

✅ 迁移旧哈希?用 password_needs_rehash()

当升级算法或调整 cost 参数时,可无缝迁移:

if (password_needs_rehash($oldHash, PASSWORD_ARGON2I, $options)) {
    $newHash = password_hash($plainPassword, PASSWORD_ARGON2I, $options);
    // 更新数据库中的密码哈希
    saveToDB($newHash);
}
⚠️ 重要提醒:绝不要自行实现盐值、迭代或哈希逻辑;不要用 base64_encode()、urlencode() 等伪装“加密”;所有密码字段在数据库中应使用 VARCHAR(255)(Argon2 哈希最长约 190 字符,bcrypt 约 60 字符)。

总结:PHP 的 password_* 函数集是经过严格审计、持续维护的工业级方案。它隐藏了盐值管理、算法演进与兼容性处理,让开发者专注业务逻辑——这才是真正的“安全即默认”。

```