# `passlib.hash.django_digest` - Django-specific Hashes

The Django web framework provides a module for storing user accounts and passwords (`django.contrib.auth`). This module’s password hashing code supports a few simple salted digests, stored using the format `id$salt$checksum` (where `id` is an identifier assigned by Django). Passlib provides support for all the hashes used up to and including Django 1.10.

## Django 1.10 Hashes

### Argon2

Django 1.10 added a wrapper for Argon2:

class passlib.hash.django_argon2

  This class implements Django 1.10’s Argon2 wrapper, and follows the PasswordHash API.

  This is identical to `argon2` itself, but with the Django-specific prefix `"argon2"` prepended.

  See argon2 for more details, the usage and behavior is identical.

  This should be compatible with the hashes generated by Django 1.10’s `Argon2PasswordHasher` class.

  Added in version 1.7.

This hash has the exact same structure as `passlib.hash.argon2`, except that it has the prefix `argon2` added. For example, the django_argon2 hash…:

    argon2$argon2i$v=19$m=256,t=1,p=1$c29tZXNhbHQ$AJFIsNZTMKTAewB4+ETN1A

…corresponds to the argon2 hash:

    argon2i$v=19$m=256,t=1,p=1$c29tZXNhbHQ$AJFIsNZTMKTAewB4+ETN1A

## Django 1.6 Hashes

Django 1.6 added one new hash:

### Bcrypt SHA256

class passlib.hash.django_bcrypt_sha256(ident=None, **kwds)

  This class implements Django 1.6’s Bcrypt+SHA256 hash, and follows the PasswordHash API.

  It supports a variable-length salt, and a variable number of rounds.

  While the algorithm and format is somewhat different, the api and options for this hash are identical to `bcrypt` itself, see bcrypt for more details.

  Added in version 1.6.2.

This hash has the exact same structure as `bcrypt`, except that it has the prefix `bcrypt$` added. For example, the django_bcrypt_sha256 hash…:

    bcrypt_sha256$$2a$06$/3OeRpbOf8/l6nPPRdZPp.nRiyYqPobEZGdNRBWihQhiFDh1ws1tu

…has the same structure as the bcrypt hash.:

    $2a$06$/3OeRpbOf8/l6nPPRdZPp.nRiyYqPobEZGdNRBWihQhiFDh1ws1tu

That said, the hash is calculated slightly differently… the password is run through sha256(), the result encoded to lowercase hexadecimal, and then handed to bcrypt proper. This very similar to passlib’s `bcrypt_sha256`, and addresses the same set of issues.

## Django 1.4 Hashes

Django 1.4 introduced a new “hashers” framework, as well as three new modern large-salt variable-cost hash algorithms:

- `django_pbkdf2_sha256` - a PBKDF2-HMAC-SHA256 based hash.

- `django_pbkdf2_sha1` - a PBKDF2-HMAC-SHA1 based hash.

- `django_bcrypt` - a wrapper around `bcrypt`.

These classes can be used directly as follows:

    >>> from passlib.hash import django_pbkdf2_sha256 as handler

    >>> # hash password
    >>> h = handler.hash("password")
    >>> h
    'pbkdf2_sha256$10000$s1w0UXDd00XB$+4ORmyvVWAQvoAEWlDgN34vlaJx1ZTZpa1pCSRey2Yk='

    >>> # verify password
    >>> handler.verify("password", h)
    True
    >>> handler.verify("eville", h)
    False

See also

the generic PasswordHash usage examples

### Interface

class passlib.hash.django_pbkdf2_sha256

  This class implements Django’s PBKDF2-HMAC-SHA256 hash, and follows the PasswordHash API.

  It supports a variable-length salt, and a variable number of rounds.

  The `using()` method accepts the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of characters drawn from the regexp range `[0-9a-zA-Z]`.

    - salt_size (int) – Optional number of characters to use when autogenerating new salts. Defaults to 12, but can be any positive value.

    - rounds (int) – Optional number of rounds to use. Defaults to 29000, but must be within `range(1,1<<32)`.

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

  This should be compatible with the hashes generated by Django 1.4’s `PBKDF2PasswordHasher` class.

  Added in version 1.6.

class passlib.hash.django_pbkdf2_sha1

  This class implements Django’s PBKDF2-HMAC-SHA1 hash, and follows the PasswordHash API.

  It supports a variable-length salt, and a variable number of rounds.

  The `using()` method accepts the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of characters drawn from the regexp range `[0-9a-zA-Z]`.

    - salt_size (int) – Optional number of characters to use when autogenerating new salts. Defaults to 12, but can be any positive value.

    - rounds (int) – Optional number of rounds to use. Defaults to 131000, but must be within `range(1,1<<32)`.

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

  This should be compatible with the hashes generated by Django 1.4’s `PBKDF2SHA1PasswordHasher` class.

  Added in version 1.6.

passlib.hash.django_bcrypt

  This class implements Django 1.4’s BCrypt wrapper, and follows the PasswordHash API.

  This is identical to `bcrypt` itself, but with the Django-specific prefix `"bcrypt$"` prepended. See passlib.hash.bcrypt - BCrypt for more details, the usage and behavior is identical.

  This should be compatible with the hashes generated by Django 1.4’s `BCryptPasswordHasher` class.

  Added in version 1.6.

### Format

An example `django_pbkdf2_sha256` hash (of `password`) is:

> `pbkdf2_sha256$10000$s1w0UXDd00XB$+4ORmyvVWAQvoAEWlDgN34vlaJx1ZTZpa1pCSRey2Yk=`

Both of Django’s PBKDF2 hashes have the same basic format, `ident$rounds$salt$checksum`, where:

- `ident` is an identifier (`pbkdf2_sha256` in the case of the example).

- `rounds` is a variable cost parameter encoded in decimal.

- `salt` consists of (usually 12) alphanumeric digits (`s1w0UXDd00XB` in the example).

- `checksum` is the base64 encoding the PBKDF2 digest.

The digest portion is generated by passing the `utf-8` encoded password, the `ascii`-encoded salt string, and the number of rounds into PBKDF2 using the HMAC-SHA256 prf; and generated a 32 byte checksum, which is then encoding using base64.

The other PBKDF2 wrapper functions similarly.

## Django 1.0 Hashes

Warning

All of the following hashes are very susceptible to brute-force attacks; since they are simple single-round salted digests. They should not be used for any purpose besides manipulating existing Django password hashes.

Django 1.0 supports some basic salted digests, as well as some legacy hashes:

- `django_salted_sha1` - simple salted SHA1 digest, Django 1.0-1.3’s default.

- `django_salted_md5` - simple salted MD5 digest.

- `django_des_crypt` - support for legacy `des_crypt` hashes, shoehorned into Django’s hash format.

These classes can be used directly as follows:

    >>> from passlib.hash import django_salted_sha1 as handler

    >>> # hash password
    >>> h = handler.hash("password")
    >>> h
    'sha1$c6218$161d1ac8ab38979c5a31cbaba4a67378e7e60845'

    >>> # verify password
    >>> handler.verify("password", h)
    True
    >>> handler.verify("eville", h)
    False

See also

the generic PasswordHash usage examples

### Interface

class passlib.hash.django_salted_md5

  This class implements Django’s Salted MD5 hash, and follows the PasswordHash API.

  It supports a variable-length salt, and uses a single round of MD5.

  The `hash()` and `genconfig()` methods accept the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of characters drawn from the regexp range `[0-9a-zA-Z]`.

    - salt_size (int) – Optional number of characters to use when autogenerating new salts. Defaults to 12, but can be any positive value.

  This should be compatible with the hashes generated by Django 1.4’s `MD5PasswordHasher` class.

class passlib.hash.django_salted_sha1

  This class implements Django’s Salted SHA1 hash, and follows the PasswordHash API.

  It supports a variable-length salt, and uses a single round of SHA1.

  The `hash()` and `genconfig()` methods accept the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of characters drawn from the regexp range `[0-9a-zA-Z]`.

    - salt_size (int) – Optional number of characters to use when autogenerating new salts. Defaults to 12, but can be any positive value.

  This should be compatible with Django 1.4’s `SHA1PasswordHasher` class.

### Format

An example `django_salted_sha1` hash (of `password`) is:

> `sha1$f8793$c4cd18eb02375a037885706d414d68d521ca18c7`

Both of Django’s salted hashes have the same basic format, `ident$salt$checksum`, where:

- `ident` is an identifier (`sha1` in the case of the example, `md5` for `django_salted_md5`).

- `salt` consists of (usually 5) lowercase hexadecimal digits (`f8793` in the example).

- `checksum` is lowercase hexadecimal encoding of the checksum.

The checksum is generated by concatenating the salt digits followed by the password, and hashing them using the specified digest (MD5 or SHA-1). The digest is then encoded to hexadecimal. If the password is unicode, it is converted to `utf-8` first.

### Security Issues

Django’s salted hashes should not be considered very secure.

- They use only a single round of digests with known collision and pre-image attacks (SHA1 & MD5).

- While it could be increased, they currently use only 20 bits of entropy in their salt, which is borderline insufficient to defeat rainbow tables.

- They digest the encoded hexadecimal salt, not the raw bytes, increasing the odds that a particular salt+password string will be present in a pre-computed tables of ascii digests.

## Des Crypt Wrapper

class passlib.hash.django_des_crypt

  This class implements Django’s `des_crypt` wrapper, and follows the PasswordHash API.

  It supports a fixed-length salt.

  The `hash()` and `genconfig()` methods accept the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, one will be autogenerated (this is recommended). If specified, it must be 2 characters, drawn from the regexp range `[./0-9A-Za-z]`.

    - truncate_error (bool) –

      By default, django_des_crypt will silently truncate passwords larger than 8 bytes. Setting `truncate_error=True` will cause `hash()` to raise a `PasswordTruncateError` instead.

      Added in version 1.7.

  This should be compatible with the hashes generated by Django 1.4’s `CryptPasswordHasher` class. Note that Django only supports this hash on Unix systems (though `django_des_crypt` is available cross-platform under Passlib).

  Changed in version 1.6: This class will now accept hashes with empty salt strings, since Django 1.4 generates them this way.

### Format

An example `django_des_crypt` hash (of `password`) is `crypt$cd1a4$cdlRbNJGImptk`; the general format is the same as the salted hashes: `ident$salt$checksum`, where:

- `ident` is the identifier `crypt`.

- `salt` is 5 lowercase hexadecimal digits (`cd1a4` in the example).

- `checksum` is a `des_crypt` hash (`cdlRbNJGImptk` in the example).

It should be noted that this class essentially just shoe-horns `des_crypt` into a format compatible with the Django salted hashes (above). It has a few quirks, such as the fact that only the first two characters of the salt are used by `des_crypt`, and they are in turn duplicated as the first two characters of the checksum.

For security issues relating to `django_des_crypt`, see `des_crypt`.

## Other Hashes

class passlib.hash.django_disabled

  This class provides disabled password behavior for Django, and follows the PasswordHash API.

  This class does not implement a hash, but instead claims the special hash string `"!"` which Django uses to indicate an account’s password has been disabled.

  - newly encrypted passwords will hash to `"!"`.

  - it rejects all passwords.

  Note

  Django 1.6 prepends a randomly generated 40-char alphanumeric string to each unusuable password. This class recognizes such strings, but for backwards compatibility, still returns `"!"`.

  See https://code.djangoproject.com/ticket/20079 for why Django appends an alphanumeric string.

  Changed in version 1.6.2: added Django 1.6 support

  Changed in version 1.7: started appending an alphanumeric string.

Note

Some older (pre-1.0) versions of Django encoded passwords using `hex_md5`, though this has been deprecated by Django, and should become increasingly rare.