mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
Fixed #20138 -- Added BCryptSHA256PasswordHasher
BCryptSHA256PasswordHasher pre-hashes the users password using SHA256 to prevent the 72 byte truncation inherient in the BCrypt algorithm.
This commit is contained in:
parent
e17fa9e877
commit
25f2acfed0
5 changed files with 87 additions and 7 deletions
|
@ -52,6 +52,7 @@ The default for :setting:`PASSWORD_HASHERS` is::
|
|||
PASSWORD_HASHERS = (
|
||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
'django.contrib.auth.hashers.SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
|
@ -79,10 +80,11 @@ To use Bcrypt as your default storage algorithm, do the following:
|
|||
py-bcrypt``, or downloading the library and installing it with ``python
|
||||
setup.py install``).
|
||||
|
||||
2. Modify :setting:`PASSWORD_HASHERS` to list ``BCryptPasswordHasher``
|
||||
2. Modify :setting:`PASSWORD_HASHERS` to list ``BCryptSHA256PasswordHasher``
|
||||
first. That is, in your settings file, you'd put::
|
||||
|
||||
PASSWORD_HASHERS = (
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
|
@ -97,6 +99,22 @@ To use Bcrypt as your default storage algorithm, do the following:
|
|||
That's it -- now your Django install will use Bcrypt as the default storage
|
||||
algorithm.
|
||||
|
||||
.. admonition:: Password truncation with BCryptPasswordHasher
|
||||
|
||||
The designers of bcrypt truncate all passwords at 72 characters which means
|
||||
that ``bcrypt(password_with_100_chars) == bcrypt(password_with_100_chars[:72])``.
|
||||
The original ``BCryptPasswordHasher`` does not have any special handling and
|
||||
thus is also subject to this hidden password length limit.
|
||||
``BCryptSHA256PasswordHasher`` fixes this by first first hashing the
|
||||
password using sha256. This prevents the password truncation and so should
|
||||
be preferred over the ``BCryptPasswordHasher``. The practical ramification
|
||||
of this truncation is pretty marginal as the average user does not have a
|
||||
password greater than 72 characters in length and even being truncated at 72
|
||||
the compute powered required to brute force bcrypt in any useful amount of
|
||||
time is still astronomical. Nonetheless, we recommend you use
|
||||
``BCryptSHA256PasswordHasher`` anyway on the principle of "better safe than
|
||||
sorry.
|
||||
|
||||
.. admonition:: Other bcrypt implementations
|
||||
|
||||
There are several other implementations that allow bcrypt to be
|
||||
|
@ -138,6 +156,7 @@ default PBKDF2 algorithm:
|
|||
'myproject.hashers.MyPBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
'django.contrib.auth.hashers.SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
|
@ -194,8 +213,8 @@ from the ``User`` model.
|
|||
provide a salt and a hashing algorithm to use, if you don't want to use the
|
||||
defaults (first entry of ``PASSWORD_HASHERS`` setting).
|
||||
Currently supported algorithms are: ``'pbkdf2_sha256'``, ``'pbkdf2_sha1'``,
|
||||
``'bcrypt'`` (see :ref:`bcrypt_usage`), ``'sha1'``, ``'md5'``,
|
||||
``'unsalted_md5'`` (only for backward compatibility) and ``'crypt'``
|
||||
``'bcrypt_sha256'`` (see :ref:`bcrypt_usage`), ``'bcrypt'``, ``'sha1'``,
|
||||
``'md5'``, ``'unsalted_md5'`` (only for backward compatibility) and ``'crypt'``
|
||||
if you have the ``crypt`` library installed. If the password argument is
|
||||
``None``, an unusable password is returned (a one that will be never
|
||||
accepted by :func:`check_password`).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue