Skip to content

Commit f2eaac3

Browse files
committed
Use bcrypt as default password hash algorithm for "native" and "auto"
1 parent 163df1e commit f2eaac3

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

src/Symfony/Component/PasswordHasher/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
---
33

44
* Add the component
5+
* Use `bcrypt` as default algorithm in `NativePasswordHasher`

src/Symfony/Component/PasswordHasher/Hasher/NativePasswordHasher.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class NativePasswordHasher implements PasswordHasherInterface
2929
private $options;
3030

3131
/**
32-
* @param string|null $algo An algorithm supported by password_hash() or null to use the stronger available algorithm
32+
* @param string|null $algo An algorithm supported by password_hash() or null to use the best available algorithm
3333
*/
3434
public function __construct(int $opsLimit = null, int $memLimit = null, int $cost = null, ?string $algo = null)
3535
{
@@ -52,11 +52,11 @@ public function __construct(int $opsLimit = null, int $memLimit = null, int $cos
5252
$algos = [1 => \PASSWORD_BCRYPT, '2y' => \PASSWORD_BCRYPT];
5353

5454
if (\defined('PASSWORD_ARGON2I')) {
55-
$this->algo = $algos[2] = $algos['argon2i'] = (string) \PASSWORD_ARGON2I;
55+
$algos[2] = $algos['argon2i'] = (string) \PASSWORD_ARGON2I;
5656
}
5757

5858
if (\defined('PASSWORD_ARGON2ID')) {
59-
$this->algo = $algos[3] = $algos['argon2id'] = (string) \PASSWORD_ARGON2ID;
59+
$algos[3] = $algos['argon2id'] = (string) \PASSWORD_ARGON2ID;
6060
}
6161

6262
if (null !== $algo) {

src/Symfony/Component/PasswordHasher/Hasher/PasswordHasherFactory.php

+11-5
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
namespace Symfony\Component\PasswordHasher\Hasher;
1313

14-
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
1514
use Symfony\Component\PasswordHasher\Exception\LogicException;
1615
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
16+
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
1717

1818
/**
1919
* A generic hasher factory implementation.
@@ -103,9 +103,15 @@ private function createHasher(array $config, bool $isExtra = false): PasswordHas
103103
private function getHasherConfigFromAlgorithm(array $config): array
104104
{
105105
if ('auto' === $config['algorithm']) {
106-
$hasherChain = [];
107106
// "plaintext" is not listed as any leaked hashes could then be used to authenticate directly
108-
foreach ([SodiumPasswordHasher::isSupported() ? 'sodium' : 'native', 'pbkdf2', $config['hash_algorithm']] as $algo) {
107+
if (SodiumPasswordHasher::isSupported()) {
108+
$algos = ['native', 'sodium', 'pbkdf2', $config['hash_algorithm']];
109+
} else {
110+
$algos = ['native', 'pbkdf2', $config['hash_algorithm']];
111+
}
112+
113+
$hasherChain = [];
114+
foreach ($algos as $algo) {
109115
$config['algorithm'] = $algo;
110116
$hasherChain[] = $this->createHasher($config, true);
111117
}
@@ -186,7 +192,7 @@ private function getHasherConfigFromAlgorithm(array $config): array
186192
$config['algorithm'] = 'native';
187193
$config['native_algorithm'] = \PASSWORD_ARGON2I;
188194
} else {
189-
throw new LogicException(sprintf('Algorithm "argon2i" is not available. Either use %s"auto" or upgrade to PHP 7.2+ instead.', \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13') ? '"argon2id", ' : ''));
195+
throw new LogicException(sprintf('Algorithm "argon2i" is not available. Use "%s" instead.', \defined('SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13') ? 'argon2id" or "auto' : 'auto'));
190196
}
191197

192198
return $this->getHasherConfigFromAlgorithm($config);
@@ -198,7 +204,7 @@ private function getHasherConfigFromAlgorithm(array $config): array
198204
$config['algorithm'] = 'native';
199205
$config['native_algorithm'] = \PASSWORD_ARGON2ID;
200206
} else {
201-
throw new LogicException(sprintf('Algorithm "argon2id" is not available. Either use %s"auto", upgrade to PHP 7.3+ or use libsodium 1.0.15+ instead.', \defined('PASSWORD_ARGON2I') || $hasSodium ? '"argon2i", ' : ''));
207+
throw new LogicException(sprintf('Algorithm "argon2id" is not available. Either use "%s", upgrade to PHP 7.3+ or use libsodium 1.0.15+ instead.', \defined('PASSWORD_ARGON2I') || $hasSodium ? 'argon2i", "auto' : 'auto'));
202208
}
203209

204210
return $this->getHasherConfigFromAlgorithm($config);

src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php

+8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ public function testConfiguredAlgorithm()
7373
$this->assertStringStartsWith('$2', $result);
7474
}
7575

76+
public function testDefaultAlgorithm()
77+
{
78+
$hasher = new NativePasswordHasher();
79+
$result = $hasher->hash('password');
80+
$this->assertTrue($hasher->verify($result, 'password'));
81+
$this->assertStringStartsWith('$2', $result);
82+
}
83+
7684
public function testConfiguredAlgorithmWithLegacyConstValue()
7785
{
7886
$hasher = new NativePasswordHasher(null, null, null, '1');

0 commit comments

Comments
 (0)