diff --git a/best_practices/security.rst b/best_practices/security.rst index 85fe1a70eed..28f9b86771c 100644 --- a/best_practices/security.rst +++ b/best_practices/security.rst @@ -38,6 +38,13 @@ of ``bcrypt`` are the inclusion of a *salt* value to protect against rainbow table attacks, and its adaptive nature, which allows to make it slower to remain resistant to brute-force search attacks. +.. note:: + + :ref:`Argon2i ` is the hashing algorithm as + recommended by industry standards, but this won't be available to you unless + you are using PHP 7.2+ or have the `libsodium`_ extension installed. + ``bcrypt`` is sufficient for most applications. + With this in mind, here is the authentication setup from our application, which uses a login form to load users from the database: @@ -397,3 +404,4 @@ Next: :doc:`/best_practices/web-assets` .. _`ParamConverter`: https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html .. _`@Security annotation`: https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html .. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle +.. _`libsodium`: https://pecl.php.net/package/libsodium diff --git a/doctrine/registration_form.rst b/doctrine/registration_form.rst index f19e684ea79..1ee421ecdfa 100644 --- a/doctrine/registration_form.rst +++ b/doctrine/registration_form.rst @@ -132,7 +132,7 @@ With some validation added, your class may look something like this:: public function getSalt() { - // The bcrypt algorithm doesn't require a separate salt. + // The bcrypt and argon2i algorithms don't require a separate salt. // You *may* need a real salt if you choose a different encoder. return null; } diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index 3be70eaffe1..8b2605cf407 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -82,6 +82,10 @@ Each part will be explained in the next section. algorithm: plaintext ignore_case: false + # Argon2i encoder + Acme\DemoBundle\Entity\User6: + algorithm: argon2i + providers: # Required # Examples: my_in_memory_provider: @@ -611,7 +615,7 @@ persisting the encoded password alone is enough. .. note:: - All the encoded passwords are ``60`` characters long, so make sure to + BCrypt encoded passwords are ``60`` characters long, so make sure to allocate enough space for them to be persisted. .. tip:: @@ -620,7 +624,63 @@ persisting the encoded password alone is enough. the cost to ``4``, which is the minimum value allowed, in the ``test`` environment configuration. - .. _reference-security-firewall-context: +.. _reference-security-argon2i: + +Using the Argon2i Password Encoder +---------------------------------- + +.. caution:: + + To use this encoder, you either need to use PHP version 7.2 or install + the `libsodium`_ extension. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + + encoders: + Symfony\Component\Security\Core\User\User: + algorithm: argon2i + + .. code-block:: xml + + + + + + + + .. code-block:: php + + // app/config/security.php + use Symfony\Component\Security\Core\User\User; + + $container->loadFromExtension('security', array( + // ... + 'encoders' => array( + User::class => array( + 'algorithm' => 'argon2i', + ), + ), + )); + +A salt for each new password is generated automatically and need not be +persisted. Since an encoded password contains the salt used to encode it, +persisting the encoded password alone is enough. + +.. note:: + + Argon2i encoded passwords are ``96`` characters long, but due to the hashing + requirements saved in the resulting hash this may change in the future. + +.. _reference-security-firewall-context: Firewall Context ---------------- @@ -749,3 +809,4 @@ To use HTTP-Digest authentication you need to provide a realm and a secret: .. _`PBKDF2`: https://en.wikipedia.org/wiki/PBKDF2 .. _`ircmaxell/password-compat`: https://packagist.org/packages/ircmaxell/password-compat +.. _`libsodium`: https://pecl.php.net/package/libsodium diff --git a/security.rst b/security.rst index d05207911eb..f8c2077d5e9 100644 --- a/security.rst +++ b/security.rst @@ -457,8 +457,8 @@ C) Encoding the User's Password ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Whether your users are stored in ``security.yml``, in a database or somewhere -else, you'll want to encode their passwords. The best algorithm to use is -``bcrypt``: +else, you'll want to encode their passwords. The most suitable algorithm to use +is ``bcrypt``: .. configuration-block:: @@ -593,8 +593,8 @@ before inserting them into the database? Don't worry, see Supported algorithms for this method depend on your PHP version, but include the algorithms returned by the PHP function :phpfunction:`hash_algos` - as well as a few others (e.g. bcrypt). See the ``encoders`` key in the - :doc:`Security Reference Section ` + as well as a few others (e.g. bcrypt and argon2i). See the ``encoders`` key + in the :doc:`Security Reference Section ` for examples. It's also possible to use different hashing algorithms on a user-by-user diff --git a/security/named_encoders.rst b/security/named_encoders.rst index 0ed0b696c29..595fb7ff71a 100644 --- a/security/named_encoders.rst +++ b/security/named_encoders.rst @@ -101,6 +101,12 @@ named encoders: ), )); +.. note:: + + If you are running PHP 7.2+ or have the `libsodium`_ extension installed, + then the recommended hashing algorithm to use is + :ref:`Argon2i `. + This creates an encoder named ``harsh``. In order for a ``User`` instance to use it, the class must implement :class:`Symfony\\Component\\Security\\Core\\Encoder\\EncoderAwareInterface`. @@ -172,3 +178,5 @@ you must register a service for it in order to use it as a named encoder: This creates an encoder named ``app_encoder`` from a service named ``app.password_encoder_service``. + +.. _`libsodium`: https://pecl.php.net/package/libsodium