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.0 起已弃用 md5() 的非二进制模式警告;实际项目中应完全避免。

❌ 原生 SHA 系列:同样不推荐

sha1()hash('sha256', ...) 同样是快速哈希,缺乏抗暴力破解能力。即使加盐,也无法抵御 GPU/ASIC 高速穷举:

// ❌ 不推荐:SHA-256 + 手动加盐(仍不安全)
$salt = "my_app_salt_2024";
$hash = hash('sha256', $salt . $password);
// 问题:无工作因子,现代硬件每秒可计算数亿次

✅ bcrypt:PHP 原生推荐方案

password_hash()password_verify() 是 PHP 内置的 bcrypt 封装(PHP 5.5+),自动处理盐值、迭代轮数(默认 cost=10),且向后兼容:

// ✅ 正确做法:一行生成强哈希
$hash = password_hash("user_password", PASSWORD_BCRYPT, ['cost' => 12]);
// 示例输出:$2y$12$X9zZvQaBcDeFgHiJkLmNoOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStU

// ✅ 验证密码(自动提取盐与参数)
if (password_verify("user_password", $hash)) {
    echo "登录成功!";
}
✅ 优势:自动生成唯一盐值、可调强度、防时序攻击、升级成本平滑(如 future 改用 Argon2)。

💡 进阶建议

  • 优先使用 PASSWORD_ARGON2ID(PHP 7.2+,需 libsodium)—— 更抗 GPU/ASIC 攻击;
  • 避免自行实现加盐/迭代逻辑,信任 password_*() 函数族;
  • 数据库字段请使用 VARCHAR(255) 存储哈希(bcrypt 最长约 60 字符,Argon2 更长)。

安全不是功能,而是基础。从今天起,请永远用 password_hash() 替代所有手写哈希逻辑。

```