php - 为什么在 Symfony 中使用相同的盐和密码调用 encodePassword()(或 hashPasswor())会产生不同的哈希?
问题描述
在UserPassword
编码器中,
public function encodePassword(UserInterface $user, string $plainPassword)
{
$encoder = $this->encoderFactory->getEncoder($user);
return $encoder->encodePassword($plainPassword, $user->getSalt());
}
编码器从用户实体获取盐。
getSalt()
我为in User 实体设置了一个静态变量:
public function getSalt()
{
return 'my-static-salt';
}
但是当我编码时:
$password = $encoder->encodePassword($user, "my-password");
$password2 = $encoder->encodePassword($user, "my-password");
$password
并且$password2
彼此不同,就好像该encodePassword()
方法使用随机盐一样。
我错过了什么?
解决方案
Symfony > 5.4 的注意事项
从 Symfony 6 开始,这些类和方法被更恰当地命名Encode
为Hash
. 并从 Security Core 包移至 Password Hasher 包:
例如,
Symfony\Component\Security\Core\Encoder\EncoderFactory
变成
Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory
,等等。
但答案的实质是一样的。
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;
}
注意这条评论:
// 忽略 $salt,自动生成的总是最好的
如果您不将盐字符串传递给password_hash()
,它会在您每次调用它时生成自己的随机生成的盐,并将盐存储在操作的结果中(以及使用的散列算法)。
(同样,SodiumPasswordEncoder
你会看到$salt
根本没有使用它,尽管不存在类似的评论)。
进一步阅读:
推荐阅读
- sql-server - 导入外部表
- azure - Azure IoT Edge 模块:构建和推送 IoT Edge 解决方案时出错
- rust - 是否可以限制 Criterion 执行的迭代次数?
- javascript - JQuery 与 getElementId - 返回内容的差异
- python - 我们如何通过程序检查任何电子邮件 ID 是否可交付(真实存在或不存在)?
- java - Java - 如何替换正在运行的 jar 文件
- c# - 关闭由另一个应用程序打开的套接字
- c++ - 使用继承时如何修复中断的控制台
- python - Python 在字符串中搜索字符串并获取该字符串背后的内容
- c# - 如何获取在一定间隔内修改的活动目录用户?