In Symfony 3.4 we introduced the Argon2i password hasher as an alternative to
the popular Bcrypt hasher. In the case of Bcrypt you can configure it with
the cost
parameter, which defines the amount of CPU power needed to hash a
password.
The Argon2i algorithm is more configurable than Bcrypt and that's why in Symfony 4.1 we've introduced several configuration options for the Argon2i hasher:
1 2 3 4 5 6 7 8 9 10
# config/packages/security.yaml
security:
# ...
encoders:
App\Entity\User:
algorithm: 'argon2i'
# maximum memory (in KiB) that may be used to compute the Argon2 hash
memory_cost: 1024
# number of times the Argon2 hash algorithm will be run
time_cost: 3
Password hashing is a fast moving field that requires continuous updates. In fact, there's an official RFC to replace the current Argon2i algorithm in the next stable PHP version by the newer Argon2id variant. Thanks to Symfony you can skip all these debates and be sure that your applications will always be safe and use the latest security best practices.
Maybe add a blog entry on how to change from a bcrypt encoder to argon2i on a already existing User entity?
Or add to it to the documentation
@Martin I agree. Let's add that to the Symfony Docs. See https://github.com/symfony/symfony-docs/issues/9356
@Martin This blog post shows a way to change password hash encoding : http://blog.michaelperrin.fr/2017/01/17/migrating-users-to-a-secure-hashing-algorithm-in-symfony/
It's simple and well explained.
@Martin @Pierre-Charles I also found a nice solution with a PHP function I hadn't even known existed:
if (password_needs_rehash($password, PASSWORD_ARGON2I, ['cost' => 11])) { $password = password_hash($password, PASSWORD_ARGON2I, ['cost' => 11]); }
The password_needs_rehash() function can determine if the encrypted password was encrypted with the algorithm specified. So:
User authenticates->If successful, while you still have the plain password they just submitted to login, check the stored password in the database. If it needs to be updated, rehash the plain password with the new algorithm and store the new hash
Obviously that's overly simplified, but allows for easy migration of say MD5->BCRYPT->ARGON2I->ARGON2D->Whatever new super algo someone comes up with
Just dug out the example I ran a few months ago and stuck it in a gist if you all want to see it: https://gist.github.com/mbadolato/5bd07bf078f1fe0fff09b83ba8c41879
@Mark Someone suggest the same method on the Github issue (https://github.com/symfony/symfony-docs/issues/9356). It seems better to secure all passwords at a time.