PHP 的 Crypt() 中的精度损失?相同的盐,不同的密码=相同的加密结果


Precision loss in PHP's Crypt()? Same salt, different passwords = same encrypted result

我在PHP中使用Crypt()来加密密码。假设盐是"bg",
密码为:"gg456456gg"

加密结果给出:"bgvQk9C2Pv27o"
但是如果我使用密码:"gg456456" - 没有最后两个字符,它会给出相同的结果。

因此,用户无需输入100%确切的密码即可登录。

发生了什么事情?我的意思是gg456456和gg456456gg是两个不同的密码,为什么加密结果相同?

在函数 crypt() 上 Php.net

基于 DES 的标准 crypt() 返回盐作为前两个 输出的字符。它也只使用前八个字符 str,因此以相同的八个字符开头的较长字符串 将产生相同的结果(当使用相同的盐时)。

因此,请使用不同的加密方法。如河豚或 sha-512。这些将接受更长的字符串

例如 SHA-512:

$encpassword = crypt($password,"$6$".$salt);

使用了上面的方法(和相同的盐):

gg456456 -> $6$631080661$L2o7HNKfYrqB4H19vYe7fRWWLenQj2EcWqriNG9rX6ki1QKO2YytkylrYmZ8mhIr6XE19Ms4RW2of5Z/dsYRA/

gg456456gg -> $6$631080661$maGxQ2d7ZIPIdXDFN1sJJsIjTFEwD9dL/uljSXdKXeJU4E5miCzh1ZCao57sGDm9PrDhdPYPLGUvoy0HzTfqI.

为您的盐使用一个好的随机数生成器,瞧,您有一个加密良好的密码

Unix系统上的原始crypt函数仅使用密码的前8个字符。最终,我们认为这是不安全的,并切换到更安全的密码哈希。

PHP crypt

函数根据您提供的盐来选择要使用的算法,并且像您使用的两字符字母数字盐会触发原始 crypt 算法。

有关算法和相应盐的列表,请参阅 http://php.net/manual/en/function.crypt.php。