php中唯一推荐的密码处理方式是直接用password_hash()生成带盐、自适应哈希值并用password_verify()校验;必须禁用md5/sha1等通用哈希,因其无盐、无迭代、易被暴力破解;password_hash()自动管理盐值、内置算法标识、支持argon2id或bcrypt,输出可存varchar(255);验证须用password_verify()防时序攻击;旧哈希可通过password_needs_rehash()平滑升级。

直接用 password_hash() 生成带盐、自适应的哈希值,存入数据库;登录时用 password_verify() 校验——这是 PHP 中唯一推荐的密码处理方式。
必须用 password_hash(),不能用 MD5/SHA1
MD5、SHA1 等通用哈希函数速度快、无盐、无迭代成本,极易被彩虹表或 GPU 暴力破解。它们不是为密码设计的。而 password_hash():
- 自动随机生成唯一盐值,无需手动拼接或管理
- 默认选用 bcrypt 或 Argon2ID(PHP ≥ 7.3),哈希字符串自带算法与参数标识
- 支持未来算法升级,输出字符串可直接存进 VARCHAR(255) 字段
- 每次调用结果都不同(因盐值唯一),这不是 bug,是安全必需
推荐写法与参数设置
生产环境建议显式指定算法和参数,避免依赖 PASSWORD_DEFAULT 的隐式变更:
- 优先选
PASSWORD_ARGON2ID:抗 ASIC/GPU 更强,可调memory_cost、time_cost、threads(需启用 libsodium 或 libargon2) - 次选
PASSWORD_BCRYPT:兼容性最好,设cost = 12(主流服务器单次约 200–400ms,安全且响应可控) - 示例:
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
验证必须用 password_verify()
登录时绝不能用 ===、strcmp() 或自己重算哈希比对:
- 只调用
password_verify($input, $stored_hash),它会自动解析盐、算法、参数并恒定时间比对,防时序攻击 - 数据库字段长度至少设为 VARCHAR(255),尤其使用 Argon2 时哈希可达 90+ 字符
- 常见失败原因:哈希被截断、密码被
trim()掉空格、读取时取错字段或返回 null
支持平滑升级旧哈希
用户下次登录时,可用 password_needs_rehash() 检测是否需更新强度:
- 例如:
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) { $newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); /* 更新数据库 */ } - 这样旧密码会逐步升级到新安全标准,不影响已有账户











