PHP程序员:6年前都告诉过你md5密码不安全,直到今天你还在犯错!

PHP程序员:6年前都告诉过你md5密码不安全,直到今天你还在犯错!
最新回答
姐,只会喝醋╯

2020-08-26 06:42:58

MD5 确实已不再安全,PHP 5.5 引入的 password_hash() 和 crypt()(如 BLOWFISH 算法)是更安全的替代方案,应优先使用这些现代密码哈希方法。

为什么 MD5 不再安全?
  • 逆向破解风险:多项研究(如论文《How to Break MD5 and Other Hash Functions》)已证明,MD5 生成的哈希值可通过“碰撞攻击”或“彩虹表”逆向破解。现代计算机可在短时间内暴力破解 MD5 哈希,尤其是弱密码。

(图:MD5 逆向攻击原理示意,来源:网络)

  • 设计缺陷:MD5 等传统哈希算法(如 SHA1、SHA256)追求计算速度,导致暴力破解成本低。安全专业人员明确建议禁止将其用于密码存储。
更安全的替代方案:password_hash() 与 crypt()1. password_hash() 函数(PHP 5.5+ 推荐)
  • 核心优势

    自适应计算成本:通过 cost 参数控制哈希计算的复杂度(如 cost=12),计算越复杂,暴力破解时间越长。

    自动加盐(Salt):每次生成哈希时自动添加随机盐值,防止彩虹表攻击。

    算法升级支持:默认使用 BCRYPT 算法,未来可无缝切换为更安全的算法(如 Argon2)。

  • 代码示例

    $options = ['cost' => 12];$hashedPassword = password_hash("user_password", PASSWORD_BCRYPT, $options);
2. crypt() 函数(BLOWFISH 算法)
  • 核心优势

    强加密算法:BLOWFISH($2a$ 前缀)是专门为密码哈希设计的算法,安全性高于 MD5。

    盐值固定格式:需手动指定盐值(如 $2a$07$usesomesillystringforsalt$),但盐值长度和格式需严格遵循规范。

  • 代码示例

    if (CRYPT_BLOWFISH == 1) { $hashedPassword = crypt('user_password', '$2a$07$usesomesillystringforsalt$');}
为什么选择 password_hash() 而非 crypt()?
  • 易用性:password_hash() 自动处理盐值和算法选择,开发者无需手动管理盐值或算法版本。
  • 安全性:password_hash() 默认使用 BCRYPT,且支持未来算法升级(如通过 PASSWORD_DEFAULT 自动适配最新算法)。
  • 验证便捷:配套的 password_verify() 函数可一键验证密码,避免手动比对哈希值的繁琐操作。
关键安全原则
  • 避免快速哈希算法:MD5、SHA1 等因计算速度快,不适合密码存储。
  • 优先使用原生 API:PHP 提供的 password_hash() 和 password_verify() 是官方推荐方案,经过严格安全审计。
  • 定期更新计算成本:随着硬件性能提升,应逐步增加 cost 值(如从 10 调整到 12),以维持破解成本。
总结

MD5 的安全性已无法满足现代应用需求,PHP 5.5 引入的 password_hash() 和 crypt()(BLOWFISH)提供了更强大的防护。开发者应立即停止使用 MD5,并迁移至 password_hash(),以低成本实现高安全性。

(图:不同哈希算法安全性对比,来源:网络)

行动建议:检查代码库中所有密码存储逻辑,将 MD5 替换为 password_hash(),并确保验证环节使用 password_verify()。安全无小事,及时升级是关键!