PHP 密码加密方案对比:MD5、SHA、bcrypt
在用户认证系统中,**安全地存储密码**是开发者的第一道防线。错误的加密方式可能让整个系统暴露于严重风险之中。本文对比三种常见方案:MD5、SHA 系列(如 SHA-256)与现代推荐方案 password_hash()(基于 bcrypt)。
❌ MD5:已淘汰,绝不用于密码
MD5 是哈希算法,但不是加密算法,且存在严重碰撞漏洞和彩虹表攻击风险。PHP 中虽仍支持,但禁止用于密码存储:
// ❌ 危险示例(仅作演示,切勿使用!)
$password = "mySecret123";
$md5_hash = md5($password); // e.g., "a1b2c3..."
// 无盐、计算极快、易被暴力破解
⚠️ SHA-256:比 MD5 强,但仍不推荐
SHA-256 抗碰撞性更好,但仍是快速哈希,攻击者可用 GPU/ASIC 高速穷举。若强行使用,必须加盐(salt)并迭代:
// ⚠️ 不推荐 —— 手动实现易出错,且仍不够慢
$salt = bin2hex(random_bytes(16));
$sha_hash = hash('sha256', $password . $salt);
// 但缺乏自适应成本因子,无法抵御算力增长
✅ bcrypt:PHP 官方推荐的现代方案
bcrypt 是专为密码设计的自适应哈希算法:内置盐值、可调计算强度(cost factor),且随硬件升级自动增强防护能力。PHP 自 5.5+ 提供原生函数:
// ✅ 推荐:一行代码完成安全哈希
$hash = password_hash("mySecret123", PASSWORD_BCRYPT, ['cost' => 12]);
// 输出类似:$2y$12$XqTQvZzK...(含盐值与参数,无需单独存储)
// 验证时同样简单:
if (password_verify("mySecret123", $hash)) {
echo "登录成功!";
}
✅ 最佳实践:始终使用
默认
password_hash() 和 password_verify()。默认
PASSWORD_BCRYPT 已足够安全;未来 PHP 可能默认升级为 Argon2(PHP 7.2+ 支持 PASSWORD_ARGON2I)。
⚠️ 注意事项:
• 不要自行拼接 salt 或使用
• 避免使用过低的 cost(如
• 数据库字段需预留至少 255 字符(bcrypt 哈希长度约 60 字符)。
• 不要自行拼接 salt 或使用
md5(sha1($pass)) 等“混淆”操作——这不增加安全性;• 避免使用过低的 cost(如
cost=4),建议 10–12(测试环境可调低);• 数据库字段需预留至少 255 字符(bcrypt 哈希长度约 60 字符)。
总结:安全不是功能,而是持续演进的责任。从今天起,请用 password_hash() 替代所有自定义哈希逻辑——让专业算法守护你的用户凭证。