Symfony 5 如何为 argon2 存储盐?
How Symfony 5 stores salt for argon2?
symfony 如何存储 argon2 的盐字符串? argon 中的盐在编码密码时是强制性的,但没有盐字符串存储在用户实体中。密码编码器中的函数支持盐作为参数,但为空且从未使用过
/vendor/symfony/security-core/Encoder/SodiumPasswordEncoder.php
public function encodePassword(string $raw, ?string $salt): string
{
if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) {
throw new BadCredentialsException('Invalid password.');
}
if (\function_exists('sodium_crypto_pwhash_str')) {
return sodium_crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit);
}
if (\extension_loaded('libsodium')) {
return \Sodium\crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit);
}
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
}
盐直接存储在哈希密码上,不需要使用单独的字段来存储盐。
未使用 $salt
参数,因为每次调用 sodium_crypto_pwhash_str
时都会生成一个随机盐,如 the docs:
中所述
Uses a CPU- and memory-hard hash algorithm along with a randomly-generated salt, and memory and CPU limits to generate an ASCII-encoded hash suitable for password storage.
return 值将包含散列密码、使用的算法、salt、内存成本、时间成本等。重新散列和验证用户提供的密码所需的一切,这就是存储在 UserInterface::$password
。
例如,呼叫:
sodium_crypto_pwhash_str('secret_string',
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
会 return 是这样的吗:
$argon2i$v=19$m=32768,t=4,p=1$smna9HfWD+caJJakZiekyQ$qbflsyuP3txLRgsGIt1alcv7HmYjfiMPanYtDU0LtCA
different parts of the response之间用$
字符隔开,分别为:
argon2i
: 使用的算法
v=19
: 版本
m=32768,t=4,p=1
:算法选项(内存成本、时间成本、要使用的线程)
smna9HfWD+caJJakZiekyQ
这是自动生成的salt。
qbflsyuP3txLRgsGIt1alcv7HmYjfiMPanYtDU0LtCA
。实际哈希值。
这是存储在 UserInterface::$password
上的内容,如您所见,它包含验证哈希所需的所有信息,包括盐。将盐存储在单独的字段中已被弃用,保留该字段只是为了向后兼容。
任何使用上述方法或推荐的 password_hash
的人都可以在没有专用盐场的情况下满足他们的所有需求。
symfony 如何存储 argon2 的盐字符串? argon 中的盐在编码密码时是强制性的,但没有盐字符串存储在用户实体中。密码编码器中的函数支持盐作为参数,但为空且从未使用过
/vendor/symfony/security-core/Encoder/SodiumPasswordEncoder.php
public function encodePassword(string $raw, ?string $salt): string
{
if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) {
throw new BadCredentialsException('Invalid password.');
}
if (\function_exists('sodium_crypto_pwhash_str')) {
return sodium_crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit);
}
if (\extension_loaded('libsodium')) {
return \Sodium\crypto_pwhash_str($raw, $this->opsLimit, $this->memLimit);
}
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
}
盐直接存储在哈希密码上,不需要使用单独的字段来存储盐。
未使用 $salt
参数,因为每次调用 sodium_crypto_pwhash_str
时都会生成一个随机盐,如 the docs:
Uses a CPU- and memory-hard hash algorithm along with a randomly-generated salt, and memory and CPU limits to generate an ASCII-encoded hash suitable for password storage.
return 值将包含散列密码、使用的算法、salt、内存成本、时间成本等。重新散列和验证用户提供的密码所需的一切,这就是存储在 UserInterface::$password
。
例如,呼叫:
sodium_crypto_pwhash_str('secret_string',
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
会 return 是这样的吗:
$argon2i$v=19$m=32768,t=4,p=1$smna9HfWD+caJJakZiekyQ$qbflsyuP3txLRgsGIt1alcv7HmYjfiMPanYtDU0LtCA
different parts of the response之间用$
字符隔开,分别为:
argon2i
: 使用的算法v=19
: 版本m=32768,t=4,p=1
:算法选项(内存成本、时间成本、要使用的线程)smna9HfWD+caJJakZiekyQ
这是自动生成的salt。qbflsyuP3txLRgsGIt1alcv7HmYjfiMPanYtDU0LtCA
。实际哈希值。
这是存储在 UserInterface::$password
上的内容,如您所见,它包含验证哈希所需的所有信息,包括盐。将盐存储在单独的字段中已被弃用,保留该字段只是为了向后兼容。
任何使用上述方法或推荐的 password_hash
的人都可以在没有专用盐场的情况下满足他们的所有需求。