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:
django_argon2
This class implements Django 1.10's Argon2 wrapper, and follows the password-hash-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.
Note
Added in 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¶
django_bcrypt_sha256
¶
django_bcrypt_sha256(ident=None, **kwds)
This class implements Django 1.6's Bcrypt+SHA256 hash, and follows the :ref:password-hash-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 :class:!bcrypt itself,
see :doc:bcrypt </lib/passlib.hash.bcrypt> for more details.
.. versionadded:: 1.6.2
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:
-
–
Trueif backend is available.Falseif it's available / can't be loaded.Noneif 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.
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 aroundbcrypt.
These classes can be used directly as follows:
from passlib.hash import django_pbkdf2_sha256 as handler
# hash password
h = handler.hash("password")
print(h)
# > 'pbkdf2_sha256$10000$s1w0UXDd00XB$+4ORmyvVWAQvoAEWlDgN34vlaJx1ZTZpa1pCSRey2Yk='
# verify password
print(handler.verify("password", h))
# > True
print(handler.verify("eville", h))
# > False
Tip
the generic PasswordHash usage examples
Interface¶
django_pbkdf2_sha256
¶
django_pbkdf2_sha256(rounds=None, **kwds)
This class implements Django's PBKDF2-HMAC-SHA256 hash, and follows the :ref:password-hash-api.
It supports a variable-length salt, and a variable number of rounds.
The :meth:~passlib.ifc.PasswordHash.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, default:None) –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 :exc:
ValueError. Ifrelaxed=True, and the error can be corrected, a :exc:~passlib.exc.PasslibHashWarningwill be issued instead. Correctable errors includeroundsthat are too small or too large, andsaltstrings that are too long.This should be compatible with the hashes generated by Django 1.4's :class:
!PBKDF2PasswordHasherclass... versionadded:: 1.6
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)
django_pbkdf2_sha1
¶
django_pbkdf2_sha1(rounds=None, **kwds)
This class implements Django's PBKDF2-HMAC-SHA1 hash, and follows the :ref:password-hash-api.
It supports a variable-length salt, and a variable number of rounds.
The :meth:~passlib.ifc.PasswordHash.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, default:None) –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 :exc:
ValueError. Ifrelaxed=True, and the error can be corrected, a :exc:~passlib.exc.PasslibHashWarningwill be issued instead. Correctable errors includeroundsthat are too small or too large, andsaltstrings that are too long.This should be compatible with the hashes generated by Django 1.4's :class:
!PBKDF2SHA1PasswordHasherclass... versionadded:: 1.6
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)
django_bcrypt()
This class implements Django 1.4's BCrypt wrapper, and follows the password-hash-api.
This is identical to bcrypt itself, but with
the Django-specific prefix "bcrypt$" prepended.
See passlib.hash.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.
Note
Added in 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_sha256in the case of the example). -
{rounds}is a variable cost parameter encoded in decimal. -
{salt}consists of (usually 12) alphanumeric digits (s1w0UXDd00XBin 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 legacydes_crypthashes, 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")
print(h)
# > 'sha1$c6218$161d1ac8ab38979c5a31cbaba4a67378e7e60845'
# verify password
print(handler.verify("password", h))
# > True
print(handler.verify("eville", h))
# > False
Tip
the generic PasswordHash usage examples
Interface¶
django_salted_md5
¶
django_salted_md5(salt=None, **kwds)
This class implements Django's Salted MD5 hash, and follows the :ref:password-hash-api.
It supports a variable-length salt, and uses a single round of MD5.
The :meth:~passlib.ifc.PasswordHash.hash and :meth:~passlib.ifc.PasswordHash.genconfig methods accept the following optional keywords:
Parameters:
-
salt(str, default:None) –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 :class:
!MD5PasswordHasherclass... versionchanged: 1.6 This class now generates 12-character salts instead of 5, and generated salts uses the character range
[0-9a-zA-Z]instead of the[0-9a-f]. This is to be compatible with how Django >= 1.4 generates these hashes; but hashes generated in this manner will still be correctly interpreted by earlier versions of Django.
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(salt_size=None, **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)
django_salted_sha1
¶
django_salted_sha1(salt=None, **kwds)
This class implements Django's Salted SHA1 hash, and follows the :ref:password-hash-api.
It supports a variable-length salt, and uses a single round of SHA1.
The :meth:~passlib.ifc.PasswordHash.hash and :meth:~passlib.ifc.PasswordHash.genconfig methods accept the following optional keywords:
Parameters:
-
salt(str, default:None) –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 :class:
!SHA1PasswordHasherclass... versionchanged: 1.6 This class now generates 12-character salts instead of 5, and generated salts uses the character range
[0-9a-zA-Z]instead of the[0-9a-f]. This is to be compatible with how Django >= 1.4 generates these hashes; but hashes generated in this manner will still be correctly interpreted by earlier versions of Django.
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(salt_size=None, **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)
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 (sha1in the case of the example,md5fordjango_salted_md5). -
{salt}consists of (usually 5) lowercase hexadecimal digits (f8793in 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¶
django_des_crypt
¶
django_des_crypt(salt=None, **kwds)
This class implements Django's :class:des_crypt wrapper, and follows the :ref:password-hash-api.
It supports a fixed-length salt.
The :meth:~passlib.ifc.PasswordHash.hash and :meth:~passlib.ifc.PasswordHash.genconfig methods accept the following optional keywords:
Parameters:
-
salt(str, default:None) –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=Truewill cause :meth:~passlib.ifc.PasswordHash.hashto raise a :exc:~passlib.exc.PasswordTruncateErrorinstead... versionadded:: 1.7This should be compatible with the hashes generated by Django 1.4's :class:
!CryptPasswordHasherclass. Note that Django only supports this hash on Unix systems (though :class:!django_des_cryptis available cross-platform under Passlib)... versionchanged:: 1.6 This class will now accept hashes with empty salt strings, since Django 1.4 generates them this way.
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(salt_size=None, **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)
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 identifiercrypt. -
{salt}is 5 lowercase hexadecimal digits (cd1a4in the example). -
{checksum}is ades_crypthash (cdlRbNJGImptkin 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¶
django_disabled
¶
django_disabled(
checksum=None, use_defaults=False, **kwds
)
This class provides disabled password behavior for Django, and follows the :ref:password-hash-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.
.. versionchanged:: 1.6.2 added Django 1.6 support
.. versionchanged:: 1.7 started appending an alphanumeric string.
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)
disable
classmethod
¶
disable(hash=None)
return string representing a 'disabled' hash; optionally including previously enabled hash (this is up to the individual scheme).
enable
classmethod
¶
enable(hash)
given a disabled-hash string, extract previously-enabled hash if one is present, otherwise raises ValueError
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.