1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
==================================================================
:class:`passlib.hash.argon2` - Argon2
==================================================================
.. versionadded:: 1.7
.. currentmodule:: passlib.hash
This hash provides support for the Argon2 [#argon2-home]_ password hash.
Argon2(i) is a state of the art memory-hard password hash, and the
winner of the 2013 Password Hashing Competition [#phc]_. It has seen active development
and analysis in subsequent years, and while young, and is intended to replace
:class:`~passlib.hash.pbkdf2_sha256`, :class:`~passlib.hash.bcrypt`, and :class:`~passlib.hash.scrypt`.
It is one of the four hashes Passlib :ref:`recommends <recommended-hashes>`
for new applications. This class can be used directly as follows::
>>> from passlib.hash import argon2
>>> # generate new salt, hash password
>>> h = argon2.hash("password")
>>> h
'$argon2i$v=19$m=512,t=2,p=2$aI2R0hpDyLm3ltLa+1/rvQ$LqPKjd6n8yniKtAithoR7A'
>>> # the same, but with an explicit number of rounds
>>> argon2.using(rounds=4).hash("password")
'$argon2i$v=19$m=512,t=4,p=2$eM+ZMyYkpDRGaI3xXmuNcQ$c5DeJg3eb5dskVt1mDdxfw'
>>> # verify password
>>> argon2.verify("password", h)
True
>>> argon2.verify("wrong", h)
False
.. seealso:: the generic :ref:`PasswordHash usage examples <password-hash-examples>`
Interface
=========
.. autoclass:: argon2()
Argon2 Backends
---------------
This class will use the first available of two possible backends:
1. `argon2_cffi <https://pypi.python.org/pypi/argon2_cffi>`_, if installed.
(this is the recommended option).
2. `argon2pure <https://pypi.python.org/pypi/argon2pure>`_, if installed.
If no backends are available, :meth:`hash` and :meth:`verify`
will throw :exc:`~passlib.exc.MissingBackendError` when they are invoked.
You can check which backend is in use by calling :meth:`!argon2.get_backend()`.
Format & Algorithm
==================
The Argon2 hash format is defined by the argon2 reference implementation.
It's compatible with the :ref:`PHC Format <phc-format>` and :ref:`modular-crypt-format`,
and uses ``$argon2i$``, ``$argon2d$``, or ``$argon2id$`` as the identifying prefixes
for all its strings. An example hash (of ``password``) is:
``$argon2i$v=19$m=512,t=3,p=2$c29tZXNhbHQ$SqlVijFGiPG+935vDSGEsA``
This string has the format :samp:`$argon2{X}$v={V}$m={M},t={T},p={P}${salt}${digest}`, where:
* :samp:`{X}` is either ``i``, ``d``, or ``id``; depending on the argon2 variant
(``i`` in the example).
* :samp:`{V}` is an integer representing the argon2 revision.
the value (when rendered into hexidecimal) matches the argon2 version
(in the example, ``v=19`` corresponds to 0x13, or Argon2 v1.3).
* :samp:`{M}` is an integer representing the variable memory cost, in kibibytes
(512kib in the example).
* :samp:`{T}` is an integer representing the variable time cost, in linear iterations.
(3 in the example).
* :samp:`{P}` is a parallelization parameter, which controls how much of the hash calculation
is parallelization (2 in the example).
* :samp:`{salt}` - this is the base64-encoded version of the raw salt bytes
passed into the Argon2 function (``c29tZXNhbHQ`` in the example).
* :samp:`{digest}` - this is the base64-encoded version of the raw derived key
bytes returned from the Argon2 function. Argon2 supports a variable
checksum size, though the hashes in passlib will typically be 16 bytes, resulting in a
22 byte digest (``SqlVijFGiPG+935vDSGEsA`` in the example).
All integer values are encoded uses ascii decimal, with no leading zeros.
All byte strings are encoded using the standard base64 encoding, but without
any trailing padding ("=") chars.
.. note::
The :samp:`v={version}$` segment was added in Argon2 v1.3; older version Argon2 v1.0
hashes may not include this portion.
The Argon2 specification also supports an optional :samp:`,data={data}` suffix
following :samp:`p={parallelism}`; but this is not consistently or fully supported.
The algorithm used by all of these schemes is deliberately identical and simple:
The password is encoded into UTF-8 if not already encoded, and handed off to the Argon2 function.
A specified number of bytes (16 byte default in passlib) returned result are encoded as the checksum.
See `<https://github.com/P-H-C/phc-winner-argon2>`_ for the canonical description of the Argon2 hash.
Security Issues
===============
Argon2 is relatively new compared to other password hash algorithms, having started life in 2013,
and thus may still harbor some undiscovered issues. That said, it's one of *very* few which were
designed explicitly with password hashing in mind; and draws strongly on the lessons of the algorithms
before it. As of the release of Passlib 1.7, it has no known major security issues.
Deviations
==========
* This implementation currently encodes all unicode passwords using UTF-8 before hashing,
other implementations may vary, or offer a configurable encoding; though UTF-8 is assumed
to be the default.
.. rubric:: Footnotes
.. [#argon2-home] the Argon2 homepage -
`<https://github.com/P-H-C/phc-winner-argon2>`_
.. [#phc] 2012 Password Hashing Competition -
`<https://password-hashing.net/>`_
|