8000 [Security/Core] make NativePasswordEncoder use sodium to validate pas… · symfony/symfony@799a2ea · GitHub
[go: up one dir, main page]

Skip to content

Commit 799a2ea

Browse files
[Security/Core] make NativePasswordEncoder use sodium to validate passwords when possible
1 parent 591ad22 commit 799a2ea

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

src/Symfony/Component/Security/Core/Encoder/NativePasswordEncoder.php

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos
4545
throw new \InvalidArgumentException('$cost must be in the range of 4-31.');
4646
}
4747

48-
$this->algo = \defined('PASSWORD_ARGON2I') ? max(PASSWORD_DEFAULT, \defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : PASSWORD_ARGON2I) : PASSWORD_DEFAULT;
48+
$this->algo = \defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : (\defined('PASSWORD_ARGON2I') ? PASSWORD_ARGON2I : PASSWORD_BCRYPT);
4949
$this->options = [
5050
'cost' => $cost,
5151
'time_cost' => $opsLimit,
@@ -59,32 +59,37 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos
5959
*/
6060
public function encodePassword($raw, $salt)
6161
{
62-
if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) {
62+
if (\strlen($raw) > self::MAX_PASSWORD_LENGTH || (PASSWORD_BCRYPT === $this->algo && 72 < \strlen($raw))) {
6363
throw new BadCredentialsException('Invalid password.');
6464
}
6565

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

68-
$encoded = password_hash($raw, $this->algo, $this->options);
69-
70-
if (72 < \strlen($raw) && 0 === strpos($encoded, '$2')) {
71-
// BCrypt encodes only the first 72 chars
72-
throw new BadCredentialsException('Invalid password.');
73-
}
74-
75-
return $encoded;
68+
return password_hash($raw, $this->algo, $this->options);
7669
}
7770

7871
/**
7972
* {@inheritdoc}
8073
*/
8174
public function isPasswordValid($encoded, $raw, $salt)
8275
{
83-
if (72 < \strlen($raw) && 0 === strpos($encoded, '$2')) {
84-
// BCrypt encodes only the first 72 chars
76+
if (\strlen($raw) > self::MAX_PASSWORD_LENGTH) {
8577
return false;
8678
}
8779

88-
return \strlen($raw) <= self::MAX_PASSWORD_LENGTH && password_verify($raw, $encoded);
80+
if (0 === strpos($encoded, '$2')) {
81+
// BCrypt encodes only the first 72 chars
82+
return 72 >= \strlen($raw) && password_verify($raw, $encoded);
83+
}
84+
85+
if (\extension_loaded('sodium') && version_compare(\SODIUM_LIBRARY_VERSION, '1.0.14', '>=')) {
86+
return sodium_crypto_pwhash_str_verify($encoded, $raw);
87+
}
88+
89+
if (\extension_loaded('libsodium') && version_compare(phpversion('libsodium'), '1.0.14', '>=')) {
90+
return \Sodium\crypto_pwhash_str_verify($encoded, $raw);
91+
}
92+
93+
return password_verify($raw, $encoded);
8994
}
9095
}
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,6 @@ public function isPasswordValid($encoded, $raw, $salt)
9393
return \Sodium\crypto_pwhash_str_verify($encoded, $raw);
9494
}
9595

96-
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
96+
return false;
9797
}
9898
}
0