PHP 哈希算法在密码存储中的应用
在 Web 应用开发中,安全地存储用户密码是开发者不可推卸的责任。明文存储密码是严重安全隐患,而简单哈希(如 md5() 或 sha1())已不再安全。PHP 提供了现代、内置的密码哈希 API,专为密码存储设计。
为什么不能用普通哈希函数?
MD5、SHA-1 等通用哈希算法计算速度快、无盐值(salt)、易受彩虹表和暴力破解攻击。2017 年起,PHP 官方明确不推荐使用 md5()、sha1() 存储密码。
⚠️ 错误示例(切勿使用):
$hash = md5($_POST['password']); // 危险!已过时且不安全
推荐方案:PHP 密码哈希 API
PHP 5.5+ 内置 password_hash() 和 password_verify() 函数,底层默认使用 bcrypt 算法(可选 argon2i 或 argon2id),自动加盐、自适应迭代次数,抗 GPU/ASIC 暴力破解。
✅ 正确实践示例
// 注册:生成安全哈希
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_ARGON2ID, [
'memory_cost' => 65536, // 64MB 内存
'time_cost' => 4, // 迭代 4 次
'threads' => 2 // 使用 2 线程(PHP ≥ 7.3)
]);
// 存入数据库(VARCHAR(255) 字段)
$stmt = $pdo->prepare("INSERT INTO users (username, password_hash) VALUES (?, ?)");
$stmt->execute([$username, $hash]);
// 登录:验证密码
$hashFromDB = $user['password_hash']; // 从数据库读取
if (password_verify($_POST['password'], $hashFromDB)) {
echo "登录成功!";
} else {
echo "密码错误。";
}
关键优势
- 自动加盐:每次调用生成唯一随机 salt,抵御彩虹表攻击;
- 算法升级友好:哈希字符串包含算法、成本参数等元信息,未来可无缝迁移至更强算法;
- 验证兼容性:
password_verify()自动识别旧哈希格式(如 bcrypt),无需手动判断; - 防时序攻击:内部采用恒定时间比较,避免侧信道泄露。
✅ 最佳实践提示:
• 使用
• 数据库字段类型设为
• 定期检查哈希是否需重哈希:
• 使用
PASSWORD_ARGON2ID(需 PHP ≥ 7.3 + libsodium)或 PASSWORD_BCRYPT(广泛兼容);• 数据库字段类型设为
VARCHAR(255)(Argon2 哈希最长约 190 字符);• 定期检查哈希是否需重哈希:
if (password_needs_rehash($hash, PASSWORD_ARGON2ID, $options)) { ... }
安全无小事。拥抱 PHP 原生密码 API,让每一次密码存储都经得起时间与算力的考验。
```