Symfony 5 如何为 argon2 存储盐?
Posted
技术标签:
【中文标题】Symfony 5 如何为 argon2 存储盐?【英文标题】:How Symfony 5 stores salt for argon2? 【发布时间】:2020-09-11 00:02:18 【问题描述】:symfony 如何为 argon2 存储盐字符串?在对密码进行编码时,氩中的盐是强制性的,但用户实体中没有存储盐字符串。密码编码器中的函数支持盐作为参数,但为空且从未使用过
/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.');
【问题讨论】:
最终 Symfony 使用password_hash 来生成哈希。除了实际的哈希和盐之外,算法及其选项(强度等)也存储在返回值中。 php 文档详细讨论了它。还有一个 password_get_info 可以解压数据。如果您想知道,UserInterface 仍然具有盐属性,只是为了向后兼容。我预计它会在 6.x 中消失。 【参考方案1】:盐直接存储在哈希密码上,不需要使用单独的字段来存储盐。
不使用$salt
参数,因为每次调用sodium_crypto_pwhash_str
都会生成随机盐,如the docs 中所述:
使用 CPU 和内存硬散列算法以及随机生成的盐,以及内存和 CPU 限制来生成适合密码存储的 ASCII 编码散列。
返回值将包含散列密码、使用的算法、盐、内存成本、时间成本等。重新散列和验证用户提供的密码所需的一切,这就是存储在 UserInterface::$password
上的内容。
例如,调用:
sodium_crypto_pwhash_str('secret_string',
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
会返回如下内容:
$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
这是自动生成的盐。
qbflsyuP3txLRgsGIt1alcv7HmYjfiMPanYtDU0LtCA
。实际的哈希值。
这是存储在UserInterface::$password
上的内容,如您所见,其中包含验证哈希所需的所有信息,包括盐。不推荐将盐存储在单独的字段中,并且仅保留该字段以实现向后兼容性。
任何使用上述方法或推荐的password_hash
的人都可以在没有专门的盐场的情况下满足他们的所有需求。
【讨论】:
好的,谢谢你的澄清。那么,请告诉我,这个字符串盐的哪一部分是?$2y$13$GplmMPH1MeZFkFJ48jjTcuLaP1TC7eTIy903KnZehhEWjQcvLaxqO
我已经测试了 argon2 (github.com/p-h-c/phc-winner-argon2) 手动提供盐,并且 argon2 在编码字符串中不包含盐。我使用“密码”作为密码,使用“XXXXXX”作为盐字符串。 Argon2 创建:$argon2i$v=19$m=65536,t=2,p=2$WFhYWFhYAHA$P2871ERltPKz+IKGGbLI6RwnLxoFIvW9+tYyBgo3pDU
所以不存储盐
我发现,WFhYWFhYAHA
这是 base64 编码的盐字符串 :)以上是关于Symfony 5 如何为 argon2 存储盐?的主要内容,如果未能解决你的问题,请参考以下文章