为什么在Symfony 4中使用相同的盐和密码调用encodePassword()会产生不同的哈希值?

tol*_*lga 3 php password-hash symfony symfony4

UserPassword 编码器中

public function encodePassword(UserInterface $user, string $plainPassword)
{
    $encoder = $this->encoderFactory->getEncoder($user);
    return $encoder->encodePassword($plainPassword, $user->getSalt());
}
Run Code Online (Sandbox Code Playgroud)

编码器从用户实体获取帮助。

我为getSalt()in User实体设置了一个静态变量:

public function getSalt()
{
    return 'my-static-salt';
}
Run Code Online (Sandbox Code Playgroud)

但是当我编码时:

$password  = $encoder->encodePassword($user, "my-password");
$password2 = $encoder->encodePassword($user, "my-password");
Run Code Online (Sandbox Code Playgroud)

$password$password2彼此不同的,因为如果该encodePassword()方法使用随机盐。

我想念什么?

yiv*_*ivi 6

EncoderFactory是,默认情况下,给你的一个实例NativePasswordEncoder(除非你安装了libsodium库,在这种情况下,它会给你一个SodiumPasswordEncoder)。

如果你看看 NativePasswordEncoder::encodePassword()你会看到这个

public function encodePassword($raw, $salt)
{
    if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) {
        throw new BadCredentialsException('Invalid password.');
    }

    // Ignore $salt, the auto-generated one is always the best

    $encoded = password_hash($raw, $this->algo, $this->options);

    if (72 < \strlen($raw) && 0 === strpos($encoded, '$2')) {
        // BCrypt encodes only the first 72 chars
        throw new BadCredentialsException('Invalid password.');
    }

    return $encoded;
}
Run Code Online (Sandbox Code Playgroud)

注意此评论:

//忽略$ salt,自动生成的总是最好的

如果您没有将salt字符串传递给password_hash(),则每次调用该字符串时,它都会生成自己的随机生成的salt,并将其存储在操作结果(以及所使用的哈希算法)中。

(类似地,尽管不存在类似的注释,但SodiumPasswordEncoder$salt 根本不会使用它)。

进一步阅读: