PHP不同版本中crypt()函数返回*0的问题求助
问题原因及解决办法
为啥会出现这个情况?
这是PHP版本对crypt()函数盐值校验规则变更导致的:
- 在PHP 5.6里,使用传统DES加密模式时,
crypt()会自动忽略盐值里前两个有效字符之外的所有内容——哪怕有!、#这种不符合DES规范的字符也不管,只拿前两个有效字符(你的盐里是aK)生成哈希。 - 从PHP 7.4开始,
crypt()对盐值的校验严格多了:DES加密只认a-z、A-Z、0-9、.、/这些字符,要是盐里混了其他字符(比如你的!),哪怕前两个字符是对的,函数也会返回*0表示加密失败。
你的盐值"aKsCg#ZTP6!$"里有#和!,刚好踩中了PHP 8.2的严格校验规则,所以出问题了。
怎么兼容已存的旧密码?
旧密码是用盐值的前两个字符aK生成的,所以在PHP 8.2里你可以这么做来验证:
只取原盐值的前两个字符当新盐值传给crypt(),生成的哈希就会和PHP 5.6里的一致了。
示例代码:
$password = "Test@1234"; // 提取原盐值的前两个字符做兼容盐 $compatible_salt = substr("aKsCg#ZTP6!$", 0, 2); $crypt_password = crypt($password, $compatible_salt); echo "crypt_password: $crypt_password <br>";
长期建议
DES加密的安全性非常差,建议趁机会把用户密码迁移到更安全的算法,比如BCrypt或者Argon2。可以在用户下次登录的时候,用新算法重新加密他们的密码,然后更新数据库里的存储值。
内容的提问来源于stack exchange,提问作者sparkmix
相关产品推荐
相关产品推荐

