mirror of https://github.com/django/django.git
Fixed #29161 -- Removed BCryptPasswordHasher from PASSWORD_HASHERS.
This commit is contained in:
parent
c4fa0143f7
commit
5b589a47b9
|
@ -512,7 +512,6 @@ PASSWORD_HASHERS = [
|
|||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
]
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = []
|
||||
|
|
|
@ -2835,7 +2835,6 @@ Default::
|
|||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
]
|
||||
|
||||
.. setting:: AUTH_PASSWORD_VALIDATORS
|
||||
|
|
|
@ -278,6 +278,23 @@ Dropped support for PostgreSQL 9.3
|
|||
The end of upstream support for PostgreSQL 9.3 is September 2018. Django 2.1
|
||||
supports PostgreSQL 9.4 and higher.
|
||||
|
||||
Removed ``BCryptPasswordHasher`` from the default ``PASSWORD_HASHERS`` setting
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you used bcrypt with Django 1.4 or 1.5 (before ``BCryptSHA256PasswordHasher``
|
||||
was added in Django 1.6), you might have some passwords that use the
|
||||
``BCryptPasswordHasher`` hasher.
|
||||
|
||||
You can check if that's the case like this::
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
User = get_user_model()
|
||||
User.objects.filter(password__startswith='bcrypt$$')
|
||||
|
||||
If you want to continue to allow those passwords to be used, you'll
|
||||
have to define the :setting:`PASSWORD_HASHERS` setting (if you don't already)
|
||||
and include ``'django.contrib.auth.hashers.BCryptPasswordHasher'``.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ The default for :setting:`PASSWORD_HASHERS` is::
|
|||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
]
|
||||
|
||||
This means that Django will use PBKDF2_ to store all passwords but will support
|
||||
|
@ -99,7 +98,6 @@ To use Argon2 as your default storage algorithm, do the following:
|
|||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
]
|
||||
|
||||
Keep and/or add any entries in this list if you need Django to :ref:`upgrade
|
||||
|
@ -126,7 +124,6 @@ To use Bcrypt as your default storage algorithm, do the following:
|
|||
|
||||
PASSWORD_HASHERS = [
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
|
@ -138,31 +135,6 @@ 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 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
|
||||
used with Django. Django's bcrypt support is NOT directly
|
||||
compatible with these. To upgrade, you will need to modify the
|
||||
hashes in your database to be in the form ``bcrypt$(raw bcrypt
|
||||
output)``. For example:
|
||||
``bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy``.
|
||||
|
||||
.. _increasing-password-algorithm-work-factor:
|
||||
|
||||
Increasing the work factor
|
||||
|
@ -202,7 +174,6 @@ default PBKDF2 algorithm:
|
|||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||
]
|
||||
|
||||
That's it -- now your Django install will use more iterations when it
|
||||
|
|
|
@ -172,6 +172,7 @@ class TestUtilsHashPass(SimpleTestCase):
|
|||
self.assertFalse(check_password(' ', blank_encoded))
|
||||
|
||||
@skipUnless(bcrypt, "bcrypt not installed")
|
||||
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.BCryptPasswordHasher'])
|
||||
def test_bcrypt(self):
|
||||
encoded = make_password('lètmein', hasher='bcrypt')
|
||||
self.assertTrue(is_password_usable(encoded))
|
||||
|
@ -187,6 +188,7 @@ class TestUtilsHashPass(SimpleTestCase):
|
|||
self.assertFalse(check_password(' ', blank_encoded))
|
||||
|
||||
@skipUnless(bcrypt, "bcrypt not installed")
|
||||
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.BCryptPasswordHasher'])
|
||||
def test_bcrypt_upgrade(self):
|
||||
hasher = get_hasher('bcrypt')
|
||||
self.assertEqual('bcrypt', hasher.algorithm)
|
||||
|
@ -219,6 +221,7 @@ class TestUtilsHashPass(SimpleTestCase):
|
|||
hasher.rounds = old_rounds
|
||||
|
||||
@skipUnless(bcrypt, "bcrypt not installed")
|
||||
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.BCryptPasswordHasher'])
|
||||
def test_bcrypt_harden_runtime(self):
|
||||
hasher = get_hasher('bcrypt')
|
||||
self.assertEqual('bcrypt', hasher.algorithm)
|
||||
|
|
Loading…
Reference in New Issue