密码绝对不能明文存库,也不能用 md5 加个固定字符串凑合——彩虹图能秒破 md5,拼接的固定盐泄露后等于没加。PHP 内置的 password_hash 就是干这个的,而且用起来只有一行:
$hash = password_hash("mySecret123", PASSWORD_DEFAULT);
// 生成类似 $2y$10$Bnmq 开头的一长串,每次运行结果都不一样
它默认使用 bcrypt 算法,并且自带随机盐,所以同一个密码每次哈希出来的字符串都不同。这也意味着,校验密码不能拿两个哈希比是否相等,只能用配套的 password_verify:
var_dump(password_verify("mySecret123", $hash)); // bool(true)
var_dump(password_verify("wrongpass", $hash)); // bool(false)
存库时字段建议留到 255 长度:PHP 未来升级默认算法后,哈希串可能变长,宽度留够就不用改表。
登录时还可以顺手做算法升级:password_needs_rehash($hash, PASSWORD_DEFAULT) 返回 true,说明这条哈希是老算法生成的,验证通过后用 password_hash 重新生成一遍再更新回库。这样算法升级时,用户密码会在下一次登录时无痛迁移。