PHP 密码加密方案对比:MD5、SHA、bcrypt

```html PHP 密码加密方案对比:MD5、SHA、bcrypt

PHP 密码加密方案对比:MD5、SHA、bcrypt

在 Web 开发中,用户密码的安全存储至关重要。选择合适的加密方案,是防止数据泄露的第一道防线。本文对比三种常见方案:已淘汰的 MD5SHA-1/SHA-256,以及现代推荐的 bcrypt

❌ MD5:绝不用于密码(已彻底弃用)

MD5 是哈希算法,但无盐值、计算极快,易被彩虹表和暴力破解攻破。PHP 中虽仍支持,但绝对禁止用于密码

// ❌ 危险示例(仅作反面演示)
$password = "123456";
$hash = md5($password); // → "e10adc3949ba59abbe56e057f20f883e"
// 无盐值、不可逆但可碰撞,毫秒级即可破解
⚠️ 警告:PHP 8.1+ 已废弃 md5() 的非二进制模式警告;8.4 将完全移除相关安全警告——因它本就不该存在。

⚠️ SHA 系列:比 MD5 强,但仍不推荐

sha1() 同样脆弱(已遭实际碰撞攻击);hash('sha256', $pass) 虽更安全,但仍是快速哈希,缺乏抗暴力设计:

// ❌ 不推荐:无盐值且速度过快
$hash = hash('sha256', $password); 

// ✅ 稍好(加盐),但盐值需安全生成且固定存储
$salt = bin2hex(random_bytes(16));
$hash = hash('sha256', $salt . $password); // 盐值必须与哈希一同存入数据库

问题在于:开发者易忽略盐值管理,且 SHA 算法本身未内置工作因子(cost factor),无法随硬件升级而增强延时。

✅ bcrypt:PHP 原生推荐的现代方案

password_hash()password_verify() 是 PHP 内置的 bcrypt 封装,自动处理盐值、可调成本(默认 cost=10),且向后兼容:

// ✅ 推荐:一行生成强哈希(含随机盐 & 自适应成本)
$hash = password_hash("mySecret123", PASSWORD_BCRYPT, ['cost' => 12]);
// → "$2y$12$ZQz...(60字符,含算法、cost、盐、密文)"

// ✅ 验证无需关心盐值或算法细节
if (password_verify("mySecret123", $hash)) {
    echo "登录成功!";
}
优势总结:自动盐值、可调计算强度(防 GPU/ASIC 暴力)、PHP 原生支持、验证接口简洁、未来可平滑升级(如迁移到 Argon2)。

结论与建议

  • 永远不要用 MD5 或 SHA-1 存储密码
  • 避免手动实现 SHA-256 + 盐(易出错,难维护);
  • 首选 password_hash() / password_verify() —— 它是 PHP 官方认证的安全实践;
  • 未来可选 PASSWORD_ARGON2ID(PHP 7.2+),但需确认服务器环境支持。

安全不是功能,而是习惯。从今天起,让每一行密码代码,都经得起时间考验。

```