Calm down
This commit is contained in:
parent
f019b29cdf
commit
9bf4953911
4
FAQ.md
4
FAQ.md
@ -3,7 +3,7 @@
|
|||||||
## I'm using *bcrypt* / *PBKDF2* / *scrypt* / *yescrypt*, do I need to migrate?
|
## I'm using *bcrypt* / *PBKDF2* / *scrypt* / *yescrypt*, do I need to migrate?
|
||||||
|
|
||||||
Using password hashes that aren't memory hard carries a certain risk but there's **no immediate danger or need for action**.
|
Using password hashes that aren't memory hard carries a certain risk but there's **no immediate danger or need for action**.
|
||||||
If however you are deciding how to hash password *today*, *Argon2* is the superior, future-proof choice.
|
If however you are deciding how to hash password *today*, Argon2 is the superior, future-proof choice.
|
||||||
|
|
||||||
But if you already use one of the hashes mentioned in the question, you should be fine for the foreseeable future.
|
But if you already use one of the hashes mentioned in the question, you should be fine for the foreseeable future.
|
||||||
If you're using *scrypt* or *yescrypt*, you will be probably fine for good.
|
If you're using *scrypt* or *yescrypt*, you will be probably fine for good.
|
||||||
@ -11,7 +11,7 @@ If you're using *scrypt* or *yescrypt*, you will be probably fine for good.
|
|||||||
|
|
||||||
## Why do the `verify()` methods raise an Exception instead of returning `False`?
|
## Why do the `verify()` methods raise an Exception instead of returning `False`?
|
||||||
|
|
||||||
1. The *Argon2* library had no concept of a "wrong password" error in the beginning.
|
1. The Argon2 library had no concept of a "wrong password" error in the beginning.
|
||||||
Therefore when writing these bindings, an exception with the full error had to be raised so you could inspect what went actually wrong.
|
Therefore when writing these bindings, an exception with the full error had to be raised so you could inspect what went actually wrong.
|
||||||
|
|
||||||
Changing that now would be a very dangerous break of backwards-compatibility.
|
Changing that now would be a very dangerous break of backwards-compatibility.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# *Argon2* for Python
|
# Argon2 for Python
|
||||||
|
|
||||||
[](https://argon2-cffi.readthedocs.io/)
|
[](https://argon2-cffi.readthedocs.io/)
|
||||||
[](https://github.com/hynek/argon2-cffi/blob/main/LICENSE)
|
[](https://github.com/hynek/argon2-cffi/blob/main/LICENSE)
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<!-- begin-short -->
|
<!-- begin-short -->
|
||||||
|
|
||||||
[*Argon2*](https://github.com/p-h-c/phc-winner-argon2) won the [Password Hashing Competition](https://www.password-hashing.net/) and *argon2-cffi* is the simplest way to use it in Python and PyPy:
|
[Argon2](https://github.com/p-h-c/phc-winner-argon2) won the [Password Hashing Competition](https://www.password-hashing.net/) and *argon2-cffi* is the simplest way to use it in Python and PyPy:
|
||||||
|
|
||||||
```pycon
|
```pycon
|
||||||
>>> from argon2 import PasswordHasher
|
>>> from argon2 import PasswordHasher
|
||||||
|
|||||||
@ -3,12 +3,12 @@ API Reference
|
|||||||
|
|
||||||
.. module:: argon2
|
.. module:: argon2
|
||||||
|
|
||||||
*argon2-cffi* comes with an high-level API and uses the officially recommended low-memory *Argon2* parameters that result in a verification time of 40--50ms on recent-ish hardware.
|
*argon2-cffi* comes with an high-level API and uses the officially recommended low-memory Argon2 parameters that result in a verification time of 40--50ms on recent-ish hardware.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
The current memory requirement is set to rather conservative 64 MB.
|
The current memory requirement is set to rather conservative 64 MB.
|
||||||
However, in memory constrained environments such as *Docker* containers that can lead to problems.
|
However, in memory constrained environments such as Docker containers that can lead to problems.
|
||||||
One possible non-obvious symptom are apparent freezes that are caused by swapping.
|
One possible non-obvious symptom are apparent freezes that are caused by swapping.
|
||||||
|
|
||||||
Please check :doc:`parameters` for more details.
|
Please check :doc:`parameters` for more details.
|
||||||
@ -219,7 +219,7 @@ Therefore it is OK to use ``argon2.low_level.ffi`` and ``argon2.low_level.lib``
|
|||||||
>>> out == argon2.low_level.hash_secret_raw(pwd, salt, 1, 8, 1, 8, Type.D)
|
>>> out == argon2.low_level.hash_secret_raw(pwd, salt, 1, 8, 1, 8, Type.D)
|
||||||
True
|
True
|
||||||
|
|
||||||
All constants and types on ``argon2.low_level.lib`` are guaranteed to stay as long they are not altered by *Argon2* itself.
|
All constants and types on ``argon2.low_level.lib`` are guaranteed to stay as long they are not altered by Argon2 itself.
|
||||||
|
|
||||||
.. autofunction:: error_to_str
|
.. autofunction:: error_to_str
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
What is *Argon2*?
|
What is Argon2?
|
||||||
=================
|
===============
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -7,14 +7,14 @@ What is *Argon2*?
|
|||||||
|
|
||||||
You do **not** need to read or understand anything below this box.
|
You do **not** need to read or understand anything below this box.
|
||||||
|
|
||||||
*Argon2* is a secure password hashing algorithm.
|
Argon2 is a secure password hashing algorithm.
|
||||||
It is designed to have both a configurable runtime as well as memory consumption.
|
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.
|
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`.
|
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 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`_.
|
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.
|
Accordingly, Argon2\ **i** was originally considered the correct choice for password hashing and password-based key derivation.
|
||||||
@ -59,7 +59,7 @@ The `Password Hashing Competition`_ took place between 2012 and 2015 to find a n
|
|||||||
Previously the NIST was in charge but after certain events and revelations_ their integrity has been put into question by the general public.
|
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.
|
So a group of independent cryptographers and security researchers came together.
|
||||||
|
|
||||||
In the end, *Argon2* was announced_ as the winner.
|
In the end, Argon2 was announced_ as the winner.
|
||||||
|
|
||||||
.. _Password Hashing Competition: https://www.password-hashing.net/
|
.. _Password Hashing Competition: https://www.password-hashing.net/
|
||||||
.. _revelations: https://en.wikipedia.org/wiki/Dual_EC_DRBG
|
.. _revelations: https://en.wikipedia.org/wiki/Dual_EC_DRBG
|
||||||
|
|||||||
@ -2,7 +2,7 @@ CLI
|
|||||||
===
|
===
|
||||||
|
|
||||||
To aid you with finding the parameters, *argon2-cffi* offers a CLI interface that can be accessed using ``python -m argon2``.
|
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:
|
It will benchmark Argon2's password *verification* in the current environment:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
==================================
|
================================
|
||||||
*argon2-cffi*: *Argon2* for Python
|
*argon2-cffi*: Argon2 for Python
|
||||||
==================================
|
================================
|
||||||
|
|
||||||
Release v\ |release| (:doc:`What's new? <changelog>`)
|
Release v\ |release| (:doc:`What's new? <changelog>`)
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
Using a Vendored *Argon2*
|
Using a Vendored Argon2
|
||||||
-------------------------
|
-----------------------
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ Using a Vendored *Argon2*
|
|||||||
|
|
||||||
should be all it takes.
|
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.
|
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).
|
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.
|
On x86, an SSE2_-optimized version is used.
|
||||||
@ -39,11 +39,11 @@ A working C compiler and `CFFI environment`_ are required to build the `argon2-c
|
|||||||
If you've been able to compile Python CFFI extensions before, *argon2-cffi* should install without any problems.
|
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*
|
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.
|
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.
|
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`_:
|
Therefore you also have to instruct *pip* to use a source distribution of `argon2-cffi-bindings`_:
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ Therefore you also have to instruct *pip* to use a source distribution of `argon
|
|||||||
env ARGON2_CFFI_USE_SYSTEM=1 \
|
env ARGON2_CFFI_USE_SYSTEM=1 \
|
||||||
python -m pip install --no-binary=argon2-cffi-bindings argon2-cffi
|
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.
|
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.**
|
**It is your own responsibility to deal with these risks if you choose this path.**
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ If you need finer tuning, the current recommended best practice is as follow:
|
|||||||
|
|
||||||
#. Choose whether you want Argon2i, Argon2d, or Argon2id (``type``).
|
#. Choose whether you want Argon2i, Argon2d, or Argon2id (``type``).
|
||||||
If you don't know what that means, choose Argon2id (:attr:`argon2.Type.ID`).
|
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).
|
#. Figure out how many threads can be used on each call to Argon2 (``parallelism``, called "lanes" in the RFC).
|
||||||
They recommend 4 threads.
|
They recommend 4 threads.
|
||||||
#. Figure out how much memory each call can afford (``memory_cost``).
|
#. Figure out how much memory each call can afford (``memory_cost``).
|
||||||
The APIs use Kibibytes_ (1024 bytes) as base unit.
|
The APIs use Kibibytes_ (1024 bytes) as base unit.
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class PasswordHasher:
|
|||||||
High level class to hash passwords with sensible defaults.
|
High level class to hash passwords with sensible defaults.
|
||||||
|
|
||||||
Uses Argon2\ **id** by default and always uses a random salt_ for hashing.
|
Uses Argon2\ **id** by default and always uses a random salt_ for hashing.
|
||||||
But it can verify any type of *Argon2* as long as the hash is correctly
|
But it can verify any type of Argon2 as long as the hash is correctly
|
||||||
encoded.
|
encoded.
|
||||||
|
|
||||||
The reason for this being a class is both for convenience to carry
|
The reason for this being a class is both for convenience to carry
|
||||||
@ -47,10 +47,10 @@ class PasswordHasher:
|
|||||||
:param int hash_len: Length of the hash in bytes.
|
:param int hash_len: Length of the hash in bytes.
|
||||||
:param int salt_len: Length of random salt to be generated for each
|
:param int salt_len: Length of random salt to be generated for each
|
||||||
password.
|
password.
|
||||||
:param str encoding: The *Argon2* C library expects bytes. So if
|
:param str encoding: The Argon2 C library expects bytes. So if
|
||||||
:meth:`hash` or :meth:`verify` are passed a ``str``, it will be
|
:meth:`hash` or :meth:`verify` are passed a ``str``, it will be
|
||||||
encoded using this encoding.
|
encoded using this encoding.
|
||||||
:param Type type: *Argon2* type to use. Only change for interoperability
|
:param Type type: Argon2 type to use. Only change for interoperability
|
||||||
with legacy systems.
|
with legacy systems.
|
||||||
|
|
||||||
.. versionadded:: 16.0.0
|
.. versionadded:: 16.0.0
|
||||||
@ -60,7 +60,7 @@ class PasswordHasher:
|
|||||||
.. versionchanged:: 18.2.0
|
.. versionchanged:: 18.2.0
|
||||||
Changed default *memory_cost* to 100 MiB and default *parallelism* to 8.
|
Changed default *memory_cost* to 100 MiB and default *parallelism* to 8.
|
||||||
.. versionchanged:: 18.2.0 ``verify`` now will determine the type of hash.
|
.. versionchanged:: 18.2.0 ``verify`` now will determine the type of hash.
|
||||||
.. versionchanged:: 18.3.0 The *Argon2* type is configurable now.
|
.. versionchanged:: 18.3.0 The Argon2 type is configurable now.
|
||||||
.. versionadded:: 21.2.0 :meth:`from_parameters`
|
.. versionadded:: 21.2.0 :meth:`from_parameters`
|
||||||
.. versionchanged:: 21.2.0
|
.. versionchanged:: 21.2.0
|
||||||
Changed defaults to :data:`argon2.profiles.RFC_9106_LOW_MEMORY`.
|
Changed defaults to :data:`argon2.profiles.RFC_9106_LOW_MEMORY`.
|
||||||
@ -194,7 +194,7 @@ class PasswordHasher:
|
|||||||
:raises argon2.exceptions.VerificationError: If verification fails for
|
:raises argon2.exceptions.VerificationError: If verification fails for
|
||||||
other reasons.
|
other reasons.
|
||||||
:raises argon2.exceptions.InvalidHash: If *hash* is so clearly
|
:raises argon2.exceptions.InvalidHash: If *hash* is so clearly
|
||||||
invalid, that it couldn't be passed to *Argon2*.
|
invalid, that it couldn't be passed to Argon2.
|
||||||
|
|
||||||
:return: ``True`` on success, raise
|
:return: ``True`` on success, raise
|
||||||
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
||||||
@ -219,7 +219,7 @@ class PasswordHasher:
|
|||||||
"""
|
"""
|
||||||
Check whether *hash* was created using the instance's parameters.
|
Check whether *hash* was created using the instance's parameters.
|
||||||
|
|
||||||
Whenever your *Argon2* parameters -- or *argon2-cffi*'s defaults! --
|
Whenever your Argon2 parameters -- or *argon2-cffi*'s defaults! --
|
||||||
change, you should rehash your passwords at the next opportunity. The
|
change, you should rehash your passwords at the next opportunity. The
|
||||||
common approach is to do that whenever a user logs in, since that
|
common approach is to do that whenever a user logs in, since that
|
||||||
should be the only time when you have access to the cleartext
|
should be the only time when you have access to the cleartext
|
||||||
|
|||||||
@ -220,7 +220,7 @@ def core(context: Any, type: int) -> int:
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
This is a strictly advanced function working on raw C data structures.
|
This is a strictly advanced function working on raw C data structures.
|
||||||
Both *Argon2*'s and *argon2-cffi*'s higher-level bindings do a lot of
|
Both Argon2's and *argon2-cffi*'s higher-level bindings do a lot of
|
||||||
sanity checks and housekeeping work that *you* are now responsible for
|
sanity checks and housekeeping work that *you* are now responsible for
|
||||||
(e.g. clearing buffers). The structure of the *context* object can,
|
(e.g. clearing buffers). The structure of the *context* object can,
|
||||||
has, and will change with *any* release!
|
has, and will change with *any* release!
|
||||||
@ -228,13 +228,13 @@ def core(context: Any, type: int) -> int:
|
|||||||
Use at your own peril; *argon2-cffi* does *not* use this binding
|
Use at your own peril; *argon2-cffi* does *not* use this binding
|
||||||
itself.
|
itself.
|
||||||
|
|
||||||
:param context: A CFFI *Argon2* context object (i.e. an ``struct
|
:param context: A CFFI Argon2 context object (i.e. an ``struct
|
||||||
Argon2_Context``/``argon2_context``).
|
Argon2_Context`` / ``argon2_context``).
|
||||||
:param int type: Which *Argon2* variant to use. You can use the ``value``
|
:param int type: Which Argon2 variant to use. You can use the ``value``
|
||||||
field of :class:`Type`'s fields.
|
field of :class:`Type`'s fields.
|
||||||
|
|
||||||
:rtype: int
|
:rtype: int
|
||||||
:return: An *Argon2* error code. Can be transformed into a string using
|
:return: An Argon2 error code. Can be transformed into a string using
|
||||||
:func:`error_to_str`.
|
:func:`error_to_str`.
|
||||||
|
|
||||||
.. versionadded:: 16.0.0
|
.. versionadded:: 16.0.0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user