Skip to content

passlib.hash.argon2 - Argon2

This hash provides support for the Argon2 1 password hash. Argon2(i) is a state of the art memory-hard password hash, and the winner of the 2013 Password Hashing Competition 2. It has seen active development and analysis in subsequent years, and while young, and is intended to replace pbkdf2_sha256, bcrypt, and scrypt.

It is one of the four hashes Passlib recommends 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")
print(h)
# > '$argon2i$v=19$m=512,t=2,p=2$aI2R0hpDyLm3ltLa+1/rvQ$LqPKjd6n8yniKtAithoR7A'

# the same, but with an explicit number of rounds
print(argon2.using(rounds=4).hash("password"))
# > '$argon2i$v=19$m=512,t=4,p=2$eM+ZMyYkpDRGaI3xXmuNcQ$c5DeJg3eb5dskVt1mDdxfw'

# verify password
print(argon2.verify("password", h))
# > True
print(argon2.verify("wrong", h))
# > False

Tip

the generic PasswordHash usage examples.

Interface

argon2

argon2(
    type=None,
    type_d=False,
    version=None,
    memory_cost=None,
    data=None,
    **kwds,
)

This class implements the Argon2 password hash [#argon2-home]_, and follows the :ref:password-hash-api.

Argon2 supports a variable-length salt, and variable time & memory cost, and a number of other configurable parameters.

The :meth:~passlib.ifc.PasswordHash.replace method accepts the following optional keywords:

Parameters:

  • type (str, default: None ) –

    Specify the type of argon2 hash to generate. Can be one of "ID", "I", "D".

    This defaults to "ID" if supported by the backend, otherwise "I".

  • salt (str) –

    Optional salt string. If specified, the length must be between 0-1024 bytes. If not specified, one will be auto-generated (this is recommended).

  • salt_size (int) –

    Optional number of bytes to use when autogenerating new salts.

  • rounds (int) –

    Optional number of rounds to use. This corresponds linearly to the amount of time hashing will take.

  • time_cost (int) –

    An alias for rounds, for compatibility with underlying argon2 library.

  • memory_cost (int, default: None ) –

    Defines the memory usage in kibibytes. This corresponds linearly to the amount of memory hashing will take.

  • parallelism (int) –

    Defines the parallelization factor. NOTE: this will affect the resulting hash value.

  • digest_size (int) –

    Length of the digest in bytes.

  • max_threads (int) –

    Maximum number of threads that will be used. -1 means unlimited; otherwise hashing will use min(parallelism, max_threads) threads.

    .. note::

    This option is currently only honored by the argon2pure backend.
    
  • relaxed (bool) –

    By default, providing an invalid value for one of the other keywords will result in a :exc:ValueError. If relaxed=True, and the error can be corrected, a :exc:~passlib.exc.PasslibHashWarning will be issued instead. Correctable errors include rounds that are too small or too large, and salt strings that are too long.

    .. versionchanged:: 1.7.2

    Added the "type" keyword, and support for type "D" and "ID" hashes.
    (Prior versions could verify type "D" hashes, but not generate them).
    

    .. todo::

    * Support configurable threading limits.
    

type_d property

type_d

flag indicating a Type D hash

.. deprecated:: 1.7.2; will be removed in passlib 2.0

encrypt classmethod

encrypt(*args, **kwds)

Legacy alias for :meth:hash.

.. deprecated:: 1.7 This method was renamed to :meth:!hash in version 1.7. This alias will be removed in version 2.0, and should only be used for compatibility with Passlib 1.3 - 1.6.

parsehash classmethod

parsehash(hash, checksum=True, sanitize=False)

[experimental method] parse hash into dictionary of settings.

this essentially acts as the inverse of :meth:hash: for most cases, if hash = cls.hash(secret, **opts), then cls.parsehash(hash) will return a dict matching the original options (with the extra keyword checksum).

this method may not work correctly for all hashes, and may not be available on some few. its interface may change in future releases, if it's kept around at all.

Parameters:

  • hash –

    hash to parse

  • checksum –

    include checksum keyword? (defaults to True)

  • sanitize –

    mask data for sensitive fields? (defaults to False)

bitsize classmethod

bitsize(rounds=None, vary_rounds=0.1, **kwds)

[experimental method] return info about bitsizes of hash

default_salt_chars

default_salt_chars()

charset used to generate new salt strings (defaults to salt_chars)

get_backend classmethod

get_backend()

Return name of currently active backend. if no backend has been loaded, loads and returns name of default backend.

Returns:

  • –

    name of active backend

Raises:

  • passlib.exc.MissingBackendError –

    if no backends are available.

has_backend classmethod

has_backend(name='any')

Check if support is currently available for specified backend.

Parameters:

  • name –

    name of backend to check for. can be any string accepted by :meth:set_backend.

Returns:

  • –
    • True if backend is available.
    • False if it's available / can't be loaded.
    • None if it's present, but won't load due to a security issue.

Raises:

  • ValueError –

    if backend name is unknown

set_backend classmethod

set_backend(name='any', dryrun=False)

Load specified backend.

Parameters:

  • name –

    name of backend to load, can be any of the following:

    • "any" -- use current backend if one is loaded, otherwise load the first available backend.

    • "default" -- use the first available backend.

    • any string in :attr:backends, loads specified backend.

  • dryrun –

    If True, this perform all setup actions except switching over to the new backend. (this flag is used to implement :meth:has_backend).

    .. versionadded:: 1.7

Raises:

  • ValueError –

    If backend name is unknown.

  • passlib.exc.MissingBackendError –

    If specific backend is missing; or in the case of "any" / "default", if no backends are available.

  • passlib.exc.PasslibSecurityError –

    If "any" or "default" was specified, but the only backend available has a PasslibSecurityError.

type_values

type_values()

return tuple of types supported by this backend

.. versionadded:: 1.7.2

Argon2 Backends

This class will use the first available of two possible backends:

  1. argon2_cffi, if installed. (this is the recommended option).

  2. argon2pure, if installed.

If no backends are available, hash() and verify() will throw MissingBackendError when they are invoked. You can check which backend is in use by calling argon2.get_backend().

Format & Algorithm

The Argon2 hash format is defined by the argon2 reference implementation. It's compatible with the PHC Format and 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 $argon2{X}$v={V}$m={M},t={T},p={P}${salt}${digest}, where:

  • {X} is either i, d, or id; depending on the argon2 variant (i in the example).

  • {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).

  • {M} is an integer representing the variable memory cost, in kibibytes (512kib in the example).

  • {T} is an integer representing the variable time cost, in linear iterations. (3 in the example).

  • {P} is a parallelization parameter, which controls how much of the hash calculation is parallelization (2 in the example).

  • {salt} - this is the base64-encoded version of the raw salt bytes passed into the Argon2 function (c29tZXNhbHQ in the example).

  • {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 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 ,data={data} suffix following 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.

  1. the Argon2 homepage - https://github.com/P-H-C/phc-winner-argon2 ↩

  2. 2012 Password Hashing Competition - https://password-hashing.net/ ↩