PHP 哈希算法在密码存储中的应用
在 Web 应用开发中,安全地存储用户密码是开发者不可推卸的责任。明文存储密码是严重安全隐患,而使用强哈希算法加盐(salt)处理则是行业标准实践。PHP 提供了内置函数,让安全密码哈希变得简单可靠。
为什么不能用普通哈希函数?
MD5、SHA-1 等快速哈希算法设计初衷并非用于密码保护——它们计算太快,易受暴力破解和彩虹表攻击。现代密码哈希必须具备:慢速性(增加穷举成本)、唯一性(每密码独立加盐)、抗碰撞性 和 标准化实现。
推荐方案:PHP 的 password_* 函数族
自 PHP 5.5 起,`password_hash()` 和 `password_verify()` 成为密码哈希的黄金标准。它们默认使用 bcrypt 算法(PHP 7.2+ 支持 Argon2i 或 Argon2id),自动处理加盐与算法参数管理。
✅ 优势:无需手动管理 salt;自动适配未来更强算法;验证时兼容旧哈希;防时序攻击。
代码示例
<?php
// 注册时:哈希密码并存入数据库
$password = "MySecureP@ssw0rd!";
$hashedPassword = password_hash($password, PASSWORD_ARGON2ID, [
'memory_cost' => 65536, // 64MB 内存
'time_cost' => 4, // 迭代次数
'threads' => 3 // 并行线程数
]);
echo "哈希后: $hashedPassword\n";
// 输出类似:$argon2id$v=19$m=65536,t=4,p=3$...$...
// 登录时:验证密码
$inputPassword = "MySecureP@ssw0rd!";
if (password_verify($inputPassword, $hashedPassword)) {
echo "✅ 密码正确!\n";
} else {
echo "❌ 密码错误。\n";
}
// 检查是否需要重新哈希(如算法升级或参数增强)
if (password_needs_rehash($hashedPassword, PASSWORD_ARGON2ID, ['time_cost' => 6])) {
$newHash = password_hash($password, PASSWORD_ARGON2ID, ['time_cost' => 6]);
// 更新数据库中的密码哈希
}
?>
重要提醒
⚠️ 切勿使用:
⚠️ 不要截断哈希值:`password_hash()` 返回的字符串长度可变(如 Argon2 最长约 255 字节),数据库字段请使用
⚠️ 禁用弱算法回退:避免设置
md5()、sha1()、crypt()(未指定强算法)或自行拼接 salt 的方式。⚠️ 不要截断哈希值:`password_hash()` 返回的字符串长度可变(如 Argon2 最长约 255 字节),数据库字段请使用
VARCHAR(255)。⚠️ 禁用弱算法回退:避免设置
PASSWORD_BCRYPT 时省略 'cost' 参数(默认 10 可能过低),建议显式配置。
安全无小事。每一次调用 password_hash(),都是对用户信任的郑重承诺。拥抱现代 PHP 的密码学原语,让哈希不止于“加密”,更成为一道坚实防线。