New in Symfony 4.3: Native password encoder

Contributed by
Nicolas Grekas
in #31140 and #31170.

Hashing passwords is one of the most critical parts of a good security system. In Symfony 4.3 we added a Sodium password encoder to hash (or "encode" as Symfony calls it for historical reasons) passwords using the libsodium library.

However, given the fast-paced evolving nature of hashers, it's less and less recommended to select a specific hashing algorithm. Even PHP's password_hash() function defines a special PASSWORD_DEFAULT value to auto-select the best possible hashing algorithm available (in current PHP versions this is still Bcrypt, but it will change in the future).

That's why in Symfony 4.3 we made some more changes related to password encoders. First, the new recommendation for hashing user passwords is to rely on the 'auto' value:

1
2
3
4
5
6
7
8
9
# config/packages/security.yaml
security:
    # ...
    encoders:
        App\Entity\User:
-            algorithm: 'bcrypt'
-            algorithm: 'argon2i'
-            algorithm: 'sodium'
+            algorithm: 'auto'

This value auto-selects the best possible hashing algorithm, so it doesn't refer to an specific algorithm and it will change in the future. The current implementation uses 'sodium' if possible and otherwise, it falls back to 'native'.

The 'native' config option is associated with the NativePasswordEncoder class, which is the other main change about password hashers in Symfony 4.3. This new encoder relies both on Symfony and PHP to select the best possible algorithm.

The current NativePasswordEncoder implementation tries to use any of the Argon2 variants (Argon2i or Argon2id) before falling back to Bcrypt. However, if the PASSWORD_DEFAULT PHP constant changes in the future, that new algorithm will be selected (if PHP defines it as stronger than Argon2).

Comments

What about rehashing of old password hashes using new algorithms? Does it happen automatically?
This means that the check password will be able to manage in the same way a password encoded with one or the other encoding method ?
doesn't that make the process too cumbersome ?
I think Symfony use the https://www.php.net/manual/en/function.password-verify.php function. Thaht function auto detect the PAssword encoding (must be supported for sure). Then, if you change the Encoder, new password use the new one, and the previous continue to work.
@Mathieu you're correct!
@Josef that's being discussed for 4.4, see https://github.com/symfony/symfony/pull/31153
Heeee Great.
@nicolas-grekas in symfony 4.3.0 the EncoderFactory::getEncoder (used by *AuthenticationProvider::checkAuthentication to fetch the correct encoder) doesn't test the current hashing method to determine which encoder to use.

So following the deprecation advise:

> Configuring an encoder with "xxx" as algorithm is deprecated since Symfony 4.3, use "auto" instead.

results in authentication failure
https://github.com/symfony/symfony/issues/31758
Great idea in principle, but what length should we now be making our password column in the database now to accommodate all the potential different hashing algorithms?
Ah thanks, this will save me having to rewrite my zf3 / doctrine encryption module :)
Login with SymfonyConnect to post a comment