php怎么加密密码_php使用password_hash加密方法【防护】

1次阅读

password_hash不可用md5或sha1替代,因其自动加盐、选算法、适配升级;后者无盐、易爆破、不安全。必须用password_verify恒定时间比对,存储字段至少varchar(255)。

php怎么加密密码_php使用password_hash加密方法【防护】

password_hash 为什么不能直接用 md5 或 sha1 替代

因为 password_hash 不只是哈希,它自动加盐、选合适算法、适配未来升级。md5 和 sha1 没盐、可暴力穷举、已被证明不安全——哪怕你手动加了随机 salt,也容易漏掉轮数控制、算法演进等细节。

  • php 8.0+ 默认用 bcrypt PASSWORD_DEFAULT),兼容性好且抗 GPU 破解
  • PASSWORD_ARGON2IPASSWORD_ARGON2ID 更强,但需编译支持 argon2 扩展,线上环境常被忽略
  • 别硬编码 cost=12:太低(如 4)易被爆破,太高(如 16)可能拖慢登录接口,建议从 10–12 起测

验证密码必须用 password_verify,不能 strcmp 或 ===

直接比对哈希值会暴露时序信息,攻击者能靠响应时间差异逐步猜出哈希——password_verify 内部做了恒定时间比较,这是它不可替代的核心价值。

  • 错误写法:if ($_hash === password_hash($input, PASSWORD_DEFAULT)) —— 完全无效,每次调用都生成新 hash
  • 正确流程:查库拿到原 hash 字符串(长度通常 60 字符),传给 password_verify($input, $stored_hash)
  • 如果数据库里存的是旧 md5,别试图“兼容验证”,应登录时用 password_needs_rehash 检测并升级

password_needs_rehash 的真实使用场景

它不是用来“定期轮换密码”的,而是应对 PHP 版本升级或策略调整后,让老用户在下次登录时无缝迁移到新 hash 格式。

  • 典型触发条件:password_needs_rehash($hash, PASSWORD_DEFAULT, ['cost' => 12]) 返回 true,说明当前 hash 不符合新参数
  • 只应在验证成功后调用:先 password_verify,再 password_needs_rehash,最后 password_hash 更新数据库
  • 别在注册时调用它——新用户直接用 password_hash 即可;也别在没验证前就 rehash,那等于把错误密码也存进去了

常见报错和存储字段长度陷阱

最常踩的坑是数据库字段太短,导致 hash 被截断,后续永远验证失败。bcrypt 默认输出 60 字符,argon2 可达 90+,而很多人还用 VARCHAR(32) 存 md5。

立即学习PHP免费学习笔记(深入)”;

  • mysql 建表务必:password_hash VARCHAR(255) NOT NULL —— 留足余量,别省那点空间
  • 报错 Invalid salt 多半是传了空字符串或非 ASCII 字符给旧版 crypt,现在应彻底弃用 crypt,只用 password_hash
  • PHP 7.4+ 开始,password_hash 对空字符串输入返回 false,别忘了检查返回值是否为 String

事情说清了就结束。真正难的不是调用函数,而是把 hash 存对位置、在对的时机验证、并且接受它“无法反解”这个事实——所有想绕过它的方案,基本都在埋雷。

text=ZqhQzanResources