summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-02-26 09:05:18 -0500
committerGitHub <noreply@github.com>2018-02-26 09:05:18 -0500
commit5b589a47b9ac2c8bdd13ba837fea37991a1457b9 (patch)
tree6a4691049c41e15b1ea10fd41ae6e008ee98c916
parentc4fa0143f7117a07a3f0258a063f5265e795ffbb (diff)
Fixed #29161 -- Removed BCryptPasswordHasher from PASSWORD_HASHERS.
-rw-r--r--django/conf/global_settings.py1
-rw-r--r--docs/ref/settings.txt1
-rw-r--r--docs/releases/2.1.txt17
-rw-r--r--docs/topics/auth/passwords.txt29
-rw-r--r--tests/auth_tests/test_hashers.py3
5 files changed, 20 insertions, 31 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 938aae8347..8efa602e1e 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -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 = []
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 152c6e339c..bc36f7c1d1 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -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
diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt
index 0a7d6da6cb..65b41b2eed 100644
--- a/docs/releases/2.1.txt
+++ b/docs/releases/2.1.txt
@@ -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
-------------
diff --git a/docs/topics/auth/passwords.txt b/docs/topics/auth/passwords.txt
index 6ae7f3d58e..4dc6748075 100644
--- a/docs/topics/auth/passwords.txt
+++ b/docs/topics/auth/passwords.txt
@@ -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
diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py
index 109aa74153..51aaa3d72c 100644
--- a/tests/auth_tests/test_hashers.py
+++ b/tests/auth_tests/test_hashers.py
@@ -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)