MyST
This commit is contained in:
parent
50c946537a
commit
4fb3ca32e3
61
docs/argon2.md
Normal file
61
docs/argon2.md
Normal file
@ -0,0 +1,61 @@
|
||||
# What is Argon2?
|
||||
|
||||
:::{note}
|
||||
**TL;DR**: Use {class}`argon2.PasswordHasher` with its default parameters to securely hash your passwords.
|
||||
|
||||
You do **not** need to read or understand anything below this box.
|
||||
:::
|
||||
|
||||
Argon2 is a secure password hashing algorithm.
|
||||
It is designed to have both a configurable runtime as well as memory consumption.
|
||||
|
||||
This means that you can decide how long it takes to hash a password and how much memory is required.
|
||||
|
||||
In September 2021, Argon2 has been standardized by the IETF in {rfc}`9106`.
|
||||
|
||||
Argon2 comes in three variants: Argon2**d**, Argon2**i**, and Argon2**id**.
|
||||
Argon2**d**'s strength is the resistance against [time–memory trade-offs], while Argon2**i**'s focus is on resistance against [side-channel attacks].
|
||||
|
||||
Accordingly, Argon2**i** was originally considered the correct choice for password hashing and password-based key derivation.
|
||||
In practice it turned out that a *combination* of d and i -- that combines their strenghts -- is the better choice.
|
||||
And so Argon2**id** was born and is now considered the *main variant* (and the only variant required by the RFC to be implemented).
|
||||
|
||||
|
||||
## Why “just use bcrypt” Is Not the Best Answer (Anymore)
|
||||
|
||||
The current workhorses of password hashing are unquestionably [*bcrypt*] and [PBKDF2].
|
||||
And while they're still fine to use, the password cracking community embraced new technologies like [GPU]s and [ASIC]s to crack password in a highly parallel fashion.
|
||||
|
||||
An effective measure against extreme parallelism proved making computation of password hashes also *memory* hard.
|
||||
The best known implementation of that approach is to date [*scrypt*].
|
||||
However according to the [Argon2 paper] [^outdated], page 2:
|
||||
|
||||
> \[…\] the existence of a trivial time-memory tradeoff allows compact implementations with the same energy cost.
|
||||
|
||||
Therefore a new algorithm was needed.
|
||||
This time future-proof and with committee-vetting instead of single implementors.
|
||||
|
||||
[^outdated]: Please note that the paper is in some parts outdated.
|
||||
For instance it predates the genesis of Argon2**id**.
|
||||
Generally please refer to {rfc}`9106` instead.
|
||||
|
||||
|
||||
## Password Hashing Competition
|
||||
|
||||
The [Password Hashing Competition] took place between 2012 and 2015 to find a new, secure, and future-proof password hashing algorithm.
|
||||
Previously the NIST was in charge but after certain events and [revelations] their integrity has been put into question by the general public.
|
||||
So a group of independent cryptographers and security researchers came together.
|
||||
|
||||
In the end, Argon2 was [announced] as the winner.
|
||||
|
||||
[announced]: https://groups.google.com/forum/#!topic/crypto-competitions/3QNdmwBS98o
|
||||
[argon2 paper]: https://www.password-hashing.net/argon2-specs.pdf
|
||||
[asic]: https://en.wikipedia.org/wiki/Application-specific_integrated_circuit
|
||||
[*bcrypt*]: https://en.wikipedia.org/wiki/Bcrypt
|
||||
[gpu]: https://hashcat.net/hashcat/
|
||||
[password hashing competition]: https://www.password-hashing.net/
|
||||
[pbkdf2]: https://en.wikipedia.org/wiki/PBKDF2
|
||||
[revelations]: https://en.wikipedia.org/wiki/Dual_EC_DRBG
|
||||
[*scrypt*]: https://en.wikipedia.org/wiki/Scrypt
|
||||
[side-channel attacks]: https://en.wikipedia.org/wiki/Side-channel_attack
|
||||
[time–memory trade-offs]: https://en.wikipedia.org/wiki/Space–time_tradeoff
|
||||
@ -1,66 +0,0 @@
|
||||
What is Argon2?
|
||||
===============
|
||||
|
||||
.. note::
|
||||
|
||||
**TL;DR**: Use :class:`argon2.PasswordHasher` with its default parameters to securely hash your passwords.
|
||||
|
||||
You do **not** need to read or understand anything below this box.
|
||||
|
||||
Argon2 is a secure password hashing algorithm.
|
||||
It is designed to have both a configurable runtime as well as memory consumption.
|
||||
|
||||
This means that you can decide how long it takes to hash a password and how much memory is required.
|
||||
|
||||
In September 2021, Argon2 has been standardized by the IETF in :rfc:`9106`.
|
||||
|
||||
Argon2 comes in three variants: Argon2\ **d**, Argon2\ **i**, and Argon2\ **id**.
|
||||
Argon2\ **d**'s strength is the resistance against `time–memory trade-offs`_, while Argon2\ **i**'s focus is on resistance against `side-channel attacks`_.
|
||||
|
||||
Accordingly, Argon2\ **i** was originally considered the correct choice for password hashing and password-based key derivation.
|
||||
In practice it turned out that a *combination* of d and i -- that combines their strenghts -- is the better choice.
|
||||
And so Argon2\ **id** was born and is now considered the *main variant* (and the only variant required by the RFC to be implemented).
|
||||
|
||||
.. _`time–memory trade-offs`: https://en.wikipedia.org/wiki/Space–time_tradeoff
|
||||
.. _`side-channel attacks`: https://en.wikipedia.org/wiki/Side-channel_attack
|
||||
|
||||
|
||||
Why “just use bcrypt” Is Not the Best Answer (Anymore)
|
||||
------------------------------------------------------
|
||||
|
||||
The current workhorses of password hashing are unquestionably bcrypt_ and PBKDF2_.
|
||||
And while they're still fine to use, the password cracking community embraced new technologies like GPU_\ s and ASIC_\ s to crack password in a highly parallel fashion.
|
||||
|
||||
An effective measure against extreme parallelism proved making computation of password hashes also *memory* hard.
|
||||
The best known implementation of that approach is to date scrypt_.
|
||||
However according to the `Argon2 paper`_ [#outdated]_, page 2:
|
||||
|
||||
[…] the existence of a trivial time-memory tradeoff allows compact implementations with the same energy cost.
|
||||
|
||||
Therefore a new algorithm was needed.
|
||||
This time future-proof and with committee-vetting instead of single implementors.
|
||||
|
||||
.. [#outdated] Please note that the paper is in some parts outdated.
|
||||
For instance it predates the genesis of Argon2\ **id**.
|
||||
Generally please refer to :rfc:`9106` instead.
|
||||
|
||||
.. _bcrypt: https://en.wikipedia.org/wiki/Bcrypt
|
||||
.. _PBKDF2: https://en.wikipedia.org/wiki/PBKDF2
|
||||
.. _GPU: https://hashcat.net/hashcat/
|
||||
.. _ASIC: https://en.wikipedia.org/wiki/Application-specific_integrated_circuit
|
||||
.. _scrypt: https://en.wikipedia.org/wiki/Scrypt
|
||||
.. _Argon2 paper: https://www.password-hashing.net/argon2-specs.pdf
|
||||
|
||||
|
||||
Password Hashing Competition
|
||||
----------------------------
|
||||
|
||||
The `Password Hashing Competition`_ took place between 2012 and 2015 to find a new, secure, and future-proof password hashing algorithm.
|
||||
Previously the NIST was in charge but after certain events and revelations_ their integrity has been put into question by the general public.
|
||||
So a group of independent cryptographers and security researchers came together.
|
||||
|
||||
In the end, Argon2 was announced_ as the winner.
|
||||
|
||||
.. _Password Hashing Competition: https://www.password-hashing.net/
|
||||
.. _revelations: https://en.wikipedia.org/wiki/Dual_EC_DRBG
|
||||
.. _announced: https://groups.google.com/forum/#!topic/crypto-competitions/3QNdmwBS98o
|
||||
24
docs/cli.md
Normal file
24
docs/cli.md
Normal file
@ -0,0 +1,24 @@
|
||||
# CLI
|
||||
|
||||
To aid you with finding the parameters, *argon2-cffi* offers a CLI interface that can be accessed using `python -m argon2`.
|
||||
It will benchmark Argon2's password *verification* in the current environment:
|
||||
|
||||
```console
|
||||
$ python -m argon2
|
||||
Running Argon2id 100 times with:
|
||||
hash_len: 32 bytes
|
||||
memory_cost: 65536 KiB
|
||||
parallelism: 4 threads
|
||||
time_cost: 3 iterations
|
||||
|
||||
Measuring...
|
||||
|
||||
45.7ms per password verification
|
||||
```
|
||||
|
||||
You can use command line arguments to set hashing parameters.
|
||||
Either by setting them one by one (`-t` for time, `-m` for memory, `-p` for parallelism, `-l` for hash length), or by passing `--profile` followed by one of the names from {mod}`argon2.profiles`.
|
||||
In that case, the other parameters are ignored.
|
||||
If you don't pass any arguments as above, it runs with {class}`argon2.PasswordHasher`'s default values.
|
||||
|
||||
This should make it much easier to determine the right parameters for your use case and your environment.
|
||||
25
docs/cli.rst
25
docs/cli.rst
@ -1,25 +0,0 @@
|
||||
CLI
|
||||
===
|
||||
|
||||
To aid you with finding the parameters, *argon2-cffi* offers a CLI interface that can be accessed using ``python -m argon2``.
|
||||
It will benchmark Argon2's password *verification* in the current environment:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ python -m argon2
|
||||
Running Argon2id 100 times with:
|
||||
hash_len: 32 bytes
|
||||
memory_cost: 65536 KiB
|
||||
parallelism: 4 threads
|
||||
time_cost: 3 iterations
|
||||
|
||||
Measuring...
|
||||
|
||||
45.7ms per password verification
|
||||
|
||||
You can use command line arguments to set hashing parameters.
|
||||
Either by setting them one by one (``-t`` for time, ``-m`` for memory, ``-p`` for parallelism, ``-l`` for hash length), or by passing ``--profile`` followed by one of the names from :mod:`argon2.profiles`.
|
||||
In that case, the other parameters are ignored.
|
||||
If you don't pass any arguments as above, it runs with :class:`argon2.PasswordHasher`'s default values.
|
||||
|
||||
This should make it much easier to determine the right parameters for your use case and your environment.
|
||||
@ -16,9 +16,7 @@ extensions = [
|
||||
"sphinx.ext.todo",
|
||||
]
|
||||
|
||||
myst_enable_extensions = [
|
||||
"deflist",
|
||||
]
|
||||
myst_enable_extensions = ["deflist", "colon_fence"]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
36
docs/index.md
Normal file
36
docs/index.md
Normal file
@ -0,0 +1,36 @@
|
||||
# *argon2-cffi*: Argon2 for Python
|
||||
|
||||
Release **{sub-ref}`release`** ([What's new?](changelog))
|
||||
|
||||
```{include} ../README.md
|
||||
:end-before: <!-- end-short -->
|
||||
:start-after: <!-- begin-short -->
|
||||
```
|
||||
|
||||
|
||||
## User's Guide
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
argon2
|
||||
installation
|
||||
api
|
||||
parameters
|
||||
cli
|
||||
faq
|
||||
changelog
|
||||
```
|
||||
|
||||
|
||||
## Project Information
|
||||
|
||||
```{include} ../README.md
|
||||
:start-after: '## Project Information'
|
||||
```
|
||||
|
||||
|
||||
## Indices and tables
|
||||
|
||||
- {ref}`genindex`
|
||||
- {ref}`search`
|
||||
@ -1,41 +0,0 @@
|
||||
================================
|
||||
*argon2-cffi*: Argon2 for Python
|
||||
================================
|
||||
|
||||
Release v\ |release| (:doc:`What's new? <changelog>`)
|
||||
|
||||
|
||||
.. include:: ../README.md
|
||||
:parser: myst_parser.sphinx_
|
||||
:start-after: <!-- begin-short -->
|
||||
:end-before: <!-- end-short -->
|
||||
|
||||
|
||||
User's Guide
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
argon2
|
||||
installation
|
||||
api
|
||||
parameters
|
||||
cli
|
||||
faq
|
||||
changelog
|
||||
|
||||
|
||||
Project Information
|
||||
===================
|
||||
|
||||
.. include:: ../README.md
|
||||
:parser: myst_parser.sphinx_
|
||||
:start-after: ## Project Information
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
73
docs/installation.md
Normal file
73
docs/installation.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Installation
|
||||
|
||||
## Using a Vendored Argon2
|
||||
|
||||
```console
|
||||
$ python -Im pip install argon2-cffi
|
||||
```
|
||||
|
||||
should be all it takes.
|
||||
|
||||
But since *argon2-cffi* depends on [argon2-cffi-bindings] that vendors Argon2's C code by default, it can lead to complications depending on the platform.
|
||||
|
||||
The C code is known to compile and work on all common platforms (including x86, ARM, and PPC).
|
||||
On x86, an [SSE2]-optimized version is used.
|
||||
|
||||
If something goes wrong, please try to update your *cffi*, *pip* and *setuptools* packages first:
|
||||
|
||||
```console
|
||||
$ python -Im pip install -U cffi pip setuptools
|
||||
```
|
||||
|
||||
Overall this should be the safest bet because *argon2-cffi* has been specifically tested against the vendored version.
|
||||
|
||||
|
||||
### Wheels
|
||||
|
||||
Binary [wheels](https://pythonwheels.com) for macOS, Windows, and Linux are provided on [PyPI] by [argon2-cffi-bindings].
|
||||
With a recent-enough *pip* and *setuptools*, they should be used automatically.
|
||||
|
||||
|
||||
### Source Distribution
|
||||
|
||||
A working C compiler and [CFFI environment] are required to build the [argon2-cffi-bindings] dependency.
|
||||
If you've been able to compile Python CFFI extensions before, *argon2-cffi* should install without any problems.
|
||||
|
||||
|
||||
## Using a System-wide Installation of Argon2
|
||||
|
||||
If you set `ARGON2_CFFI_USE_SYSTEM` to `1` (and *only* `1`), *argon2-cffi-bindings* will not build its bindings.
|
||||
However binary wheels are preferred by *pip* and Argon2 gets installed along with *argon2-cffi* anyway.
|
||||
|
||||
Therefore you also have to instruct *pip* to use a source distribution of [argon2-cffi-bindings]:
|
||||
|
||||
```console
|
||||
$ env ARGON2_CFFI_USE_SYSTEM=1 \
|
||||
python -m pip install --no-binary=argon2-cffi-bindings argon2-cffi
|
||||
```
|
||||
|
||||
This approach can lead to problems around your build chain and you can run into incompatibilities between Argon2 and *argon2-cffi* if the latter has been tested against a different version.
|
||||
|
||||
**It is your own responsibility to deal with these risks if you choose this path.**
|
||||
|
||||
Available since version 18.1.0.
|
||||
The `--no-binary` option value changed in 21.2.0 due to the outsourcing of the binary bindings.
|
||||
|
||||
|
||||
## Override Automatic SSE2 Detection
|
||||
|
||||
Usually the build process tries to guess whether or not it should use [SSE2]-optimized code.
|
||||
Despite our best efforts, this can go wrong.
|
||||
|
||||
Therefore you can use the `ARGON2_CFFI_USE_SSE2` environment variable to control the process:
|
||||
|
||||
- If you set it to `1`, *argon2-cffi* will build **with** SSE2 support.
|
||||
- If you set it to `0`, *argon2-cffi* will build **without** SSE2 support.
|
||||
- If you set it to anything else, it will be ignored and *argon2-cffi* will try to guess.
|
||||
|
||||
Available since version 20.1.0.
|
||||
|
||||
[argon2-cffi-bindings]: https://github.com/hynek/argon2-cffi-bindings
|
||||
[cffi environment]: https://cffi.readthedocs.io/en/latest/installation.html
|
||||
[pypi]: https://pypi.org/project/argon2-cffi-bindings/
|
||||
[sse2]: https://en.wikipedia.org/wiki/SSE2
|
||||
@ -1,81 +0,0 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Using a Vendored Argon2
|
||||
-----------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m pip install argon2-cffi
|
||||
|
||||
should be all it takes.
|
||||
|
||||
But since *argon2-cffi* depends on `argon2-cffi-bindings`_ that vendors Argon2's C code by default, it can lead to complications depending on the platform.
|
||||
|
||||
The C code is known to compile and work on all common platforms (including x86, ARM, and PPC).
|
||||
On x86, an SSE2_-optimized version is used.
|
||||
|
||||
If something goes wrong, please try to update your *cffi*, *pip* and *setuptools* packages first:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m pip install -U cffi pip setuptools
|
||||
|
||||
|
||||
Overall this should be the safest bet because *argon2-cffi* has been specifically tested against the vendored version.
|
||||
|
||||
|
||||
Wheels
|
||||
^^^^^^
|
||||
|
||||
Binary `wheels <https://pythonwheels.com>`_ for macOS, Windows, and Linux are provided on PyPI_ by `argon2-cffi-bindings`_.
|
||||
With a recent-enough *pip* and *setuptools*, they should be used automatically.
|
||||
|
||||
|
||||
Source Distribution
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A working C compiler and `CFFI environment`_ are required to build the `argon2-cffi-bindings`_ dependency.
|
||||
If you've been able to compile Python CFFI extensions before, *argon2-cffi* should install without any problems.
|
||||
|
||||
|
||||
Using a System-wide Installation of Argon2
|
||||
------------------------------------------
|
||||
|
||||
If you set ``ARGON2_CFFI_USE_SYSTEM`` to ``1`` (and *only* ``1``), *argon2-cffi-bindings* will not build its bindings.
|
||||
However binary wheels are preferred by *pip* and Argon2 gets installed along with *argon2-cffi* anyway.
|
||||
|
||||
Therefore you also have to instruct *pip* to use a source distribution of `argon2-cffi-bindings`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
env ARGON2_CFFI_USE_SYSTEM=1 \
|
||||
python -m pip install --no-binary=argon2-cffi-bindings argon2-cffi
|
||||
|
||||
This approach can lead to problems around your build chain and you can run into incompatibilities between Argon2 and *argon2-cffi* if the latter has been tested against a different version.
|
||||
|
||||
**It is your own responsibility to deal with these risks if you choose this path.**
|
||||
|
||||
Available since version 18.1.0.
|
||||
The ``--no-binary`` option value changed in 21.2.0 due to the outsourcing of the binary bindings.
|
||||
|
||||
|
||||
Override Automatic SSE2 Detection
|
||||
---------------------------------
|
||||
|
||||
Usually the build process tries to guess whether or not it should use SSE2_-optimized code.
|
||||
Despite our best efforts, this can go wrong.
|
||||
|
||||
Therefore you can use the ``ARGON2_CFFI_USE_SSE2`` environment variable to control the process:
|
||||
|
||||
- If you set it to ``1``, *argon2-cffi* will build **with** SSE2 support.
|
||||
- If you set it to ``0``, *argon2-cffi* will build **without** SSE2 support.
|
||||
- If you set it to anything else, it will be ignored and *argon2-cffi* will try to guess.
|
||||
|
||||
Available since version 20.1.0.
|
||||
|
||||
|
||||
.. _SSE2: https://en.wikipedia.org/wiki/SSE2
|
||||
.. _PyPI: https://pypi.org/project/argon2-cffi-bindings/
|
||||
.. _CFFI environment: https://cffi.readthedocs.io/en/latest/installation.html
|
||||
.. _`argon2-cffi-bindings`: https://github.com/hynek/argon2-cffi-bindings
|
||||
54
docs/parameters.md
Normal file
54
docs/parameters.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Choosing Parameters
|
||||
|
||||
:::{note}
|
||||
You can probably just use {class}`argon2.PasswordHasher` with its default values and be fine.
|
||||
But it's good to double check using *argon2-cffi*'s {doc}`cli` client, whether its defaults are too slow or too fast for your use case.
|
||||
:::
|
||||
|
||||
Finding the right parameters for a password hashing algorithm is a daunting task.
|
||||
As of September 2021, we have the official Internet standard [RFC 9106] to help use with it.
|
||||
|
||||
It comes with two recommendations in [section 4](https://www.rfc-editor.org/rfc/rfc9106.html#section-4), that (as of *argon2-cffi* 21.2.0) you can load directly from the {mod}`argon2.profiles` module: {data}`argon2.profiles.RFC_9106_HIGH_MEMORY` (called "FIRST RECOMMENDED") and {data}`argon2.profiles.RFC_9106_LOW_MEMORY` ("SECOND RECOMMENDED") into {meth}`argon2.PasswordHasher.from_parameters()`.
|
||||
|
||||
Please use the {doc}`cli` interface together with its `--profile` argument to see if they work for you.
|
||||
|
||||
______________________________________________________________________
|
||||
|
||||
If you need finer tuning, the current recommended best practice is as follow:
|
||||
|
||||
1. Choose whether you want Argon2i, Argon2d, or Argon2id (`type`).
|
||||
If you don't know what that means, choose Argon2id ({attr}`argon2.Type.ID`).
|
||||
|
||||
2. Figure out how many threads can be used on each call to Argon2 (`parallelism`, called "lanes" in the RFC).
|
||||
They recommend 4 threads.
|
||||
|
||||
3. Figure out how much memory each call can afford (`memory_cost`).
|
||||
The APIs use [Kibibytes] (1024 bytes) as base unit.
|
||||
|
||||
4. Select the salt length.
|
||||
16 bytes is sufficient for all applications, but can be reduced to 8 bytes in the case of space constraints.
|
||||
|
||||
5. Choose a hash length (`hash_len`, called "tag length" in the documentation).
|
||||
16 bytes is sufficient for password verification.
|
||||
|
||||
6. Figure out how long each call can take.
|
||||
One [recommendation](https://web.archive.org/web/20160304024620/https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2015/march/enough-with-the-salts-updates-on-secure-password-schemes/) for concurrent user logins is to keep it under 0.5 ms.
|
||||
The RFC used to recommend under 500 ms.
|
||||
The truth is somewhere between those two values: more is more secure, less is a better user experience.
|
||||
*argon2-cffi*'s current defaults land with ~50ms somewhere in the middle, but the actual time depends on your hardware.
|
||||
|
||||
Please note though, that even a verification time of 1 second won't protect you against bad passwords from the "top 10,000 passwords" lists that you can find online.
|
||||
|
||||
7. Measure the time for hashing using your chosen parameters.
|
||||
Start with `time_cost=1` and measure the time it takes.
|
||||
Raise `time_cost` until it is within your accounted time.
|
||||
If `time_cost=1` takes too long, lower `memory_cost`.
|
||||
|
||||
*argon2-cffi*'s {doc}`cli` will help you with this process.
|
||||
|
||||
:::{note}
|
||||
Alternatively, you can also refer to the [OWASP cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id).
|
||||
:::
|
||||
|
||||
[kibibytes]: https://en.wikipedia.org/wiki/Kibibyte
|
||||
[rfc 9106]: https://www.rfc-editor.org/rfc/rfc9106.html
|
||||
@ -1,51 +0,0 @@
|
||||
Choosing Parameters
|
||||
===================
|
||||
|
||||
.. note::
|
||||
|
||||
You can probably just use :class:`argon2.PasswordHasher` with its default values and be fine.
|
||||
But it's good to double check using *argon2-cffi*'s :doc:`cli` client, whether its defaults are too slow or too fast for your use case.
|
||||
|
||||
Finding the right parameters for a password hashing algorithm is a daunting task.
|
||||
As of September 2021, we have the official Internet standard `RFC 9106`_ to help use with it.
|
||||
|
||||
It comes with two recommendations in `section 4 <https://www.rfc-editor.org/rfc/rfc9106.html#section-4>`_, that (as of *argon2-cffi* 21.2.0) you can load directly from the :mod:`argon2.profiles` module: :data:`argon2.profiles.RFC_9106_HIGH_MEMORY` (called "FIRST RECOMMENDED") and :data:`argon2.profiles.RFC_9106_LOW_MEMORY` ("SECOND RECOMMENDED") into :meth:`argon2.PasswordHasher.from_parameters()`.
|
||||
|
||||
Please use the :doc:`cli` interface together with its ``--profile`` argument to see if they work for you.
|
||||
|
||||
----
|
||||
|
||||
If you need finer tuning, the current recommended best practice is as follow:
|
||||
|
||||
#. Choose whether you want Argon2i, Argon2d, or Argon2id (``type``).
|
||||
If you don't know what that means, choose Argon2id (:attr:`argon2.Type.ID`).
|
||||
#. Figure out how many threads can be used on each call to Argon2 (``parallelism``, called "lanes" in the RFC).
|
||||
They recommend 4 threads.
|
||||
#. Figure out how much memory each call can afford (``memory_cost``).
|
||||
The APIs use Kibibytes_ (1024 bytes) as base unit.
|
||||
#. Select the salt length.
|
||||
16 bytes is sufficient for all applications, but can be reduced to 8 bytes in the case of space constraints.
|
||||
#. Choose a hash length (``hash_len``, called "tag length" in the documentation).
|
||||
16 bytes is sufficient for password verification.
|
||||
#. Figure out how long each call can take.
|
||||
One `recommendation <https://web.archive.org/web/20160304024620/https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2015/march/enough-with-the-salts-updates-on-secure-password-schemes/>`_ for concurrent user logins is to keep it under 0.5 ms.
|
||||
The RFC used to recommend under 500 ms.
|
||||
The truth is somewhere between those two values: more is more secure, less is a better user experience.
|
||||
*argon2-cffi*'s current defaults land with ~50ms somewhere in the middle, but the actual time depends on your hardware.
|
||||
|
||||
Please note though, that even a verification time of 1 second won't protect you against bad passwords from the "top 10,000 passwords" lists that you can find online.
|
||||
#. Measure the time for hashing using your chosen parameters.
|
||||
Start with ``time_cost=1`` and measure the time it takes.
|
||||
Raise ``time_cost`` until it is within your accounted time.
|
||||
If ``time_cost=1`` takes too long, lower ``memory_cost``.
|
||||
|
||||
*argon2-cffi*'s :doc:`cli` will help you with this process.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Alternatively, you can also refer to the `OWASP cheatsheet <https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id>`_.
|
||||
|
||||
|
||||
.. _`RFC 9106`: https://www.rfc-editor.org/rfc/rfc9106.html
|
||||
.. _kibibytes: https://en.wikipedia.org/wiki/Kibibyte
|
||||
Loading…
Reference in New Issue
Block a user