Fixed #30472 -- Made Argon2PasswordHasher use Argon2id.
This commit is contained in:
parent
faad809e09
commit
1621f06051
|
@ -302,8 +302,8 @@ class Argon2PasswordHasher(BasePasswordHasher):
|
||||||
library = 'argon2'
|
library = 'argon2'
|
||||||
|
|
||||||
time_cost = 2
|
time_cost = 2
|
||||||
memory_cost = 512
|
memory_cost = 102400
|
||||||
parallelism = 2
|
parallelism = 8
|
||||||
|
|
||||||
def encode(self, password, salt):
|
def encode(self, password, salt):
|
||||||
argon2 = self._load_library()
|
argon2 = self._load_library()
|
||||||
|
@ -363,7 +363,7 @@ class Argon2PasswordHasher(BasePasswordHasher):
|
||||||
argon2 = self._load_library()
|
argon2 = self._load_library()
|
||||||
# salt_len is a noop, because we provide our own salt.
|
# salt_len is a noop, because we provide our own salt.
|
||||||
return argon2.Parameters(
|
return argon2.Parameters(
|
||||||
type=argon2.low_level.Type.I,
|
type=argon2.low_level.Type.ID,
|
||||||
version=argon2.low_level.ARGON2_VERSION,
|
version=argon2.low_level.ARGON2_VERSION,
|
||||||
salt_len=argon2.DEFAULT_RANDOM_SALT_LENGTH,
|
salt_len=argon2.DEFAULT_RANDOM_SALT_LENGTH,
|
||||||
hash_len=argon2.DEFAULT_HASH_LENGTH,
|
hash_len=argon2.DEFAULT_HASH_LENGTH,
|
||||||
|
|
|
@ -50,6 +50,15 @@ Minor features
|
||||||
* The default iteration count for the PBKDF2 password hasher is increased from
|
* The default iteration count for the PBKDF2 password hasher is increased from
|
||||||
216,000 to 260,000.
|
216,000 to 260,000.
|
||||||
|
|
||||||
|
* The default variant for the Argon2 password hasher is changed to Argon2id.
|
||||||
|
``memory_cost`` and ``parallelism`` are increased to 102,400 and 8
|
||||||
|
respectively to match the ``argon2-cffi`` defaults.
|
||||||
|
|
||||||
|
Increasing the ``memory_cost`` pushes the required memory from 512 KB to 100
|
||||||
|
MB. This is still rather conservative but can lead to problems in memory
|
||||||
|
constrained environments. If this is the case, the existing hasher can be
|
||||||
|
subclassed to override the defaults.
|
||||||
|
|
||||||
:mod:`django.contrib.contenttypes`
|
:mod:`django.contrib.contenttypes`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -497,13 +497,13 @@ class TestUtilsHashPassArgon2(SimpleTestCase):
|
||||||
def test_argon2(self):
|
def test_argon2(self):
|
||||||
encoded = make_password('lètmein', hasher='argon2')
|
encoded = make_password('lètmein', hasher='argon2')
|
||||||
self.assertTrue(is_password_usable(encoded))
|
self.assertTrue(is_password_usable(encoded))
|
||||||
self.assertTrue(encoded.startswith('argon2$'))
|
self.assertTrue(encoded.startswith('argon2$argon2id$'))
|
||||||
self.assertTrue(check_password('lètmein', encoded))
|
self.assertTrue(check_password('lètmein', encoded))
|
||||||
self.assertFalse(check_password('lètmeinz', encoded))
|
self.assertFalse(check_password('lètmeinz', encoded))
|
||||||
self.assertEqual(identify_hasher(encoded).algorithm, 'argon2')
|
self.assertEqual(identify_hasher(encoded).algorithm, 'argon2')
|
||||||
# Blank passwords
|
# Blank passwords
|
||||||
blank_encoded = make_password('', hasher='argon2')
|
blank_encoded = make_password('', hasher='argon2')
|
||||||
self.assertTrue(blank_encoded.startswith('argon2$'))
|
self.assertTrue(blank_encoded.startswith('argon2$argon2id$'))
|
||||||
self.assertTrue(is_password_usable(blank_encoded))
|
self.assertTrue(is_password_usable(blank_encoded))
|
||||||
self.assertTrue(check_password('', blank_encoded))
|
self.assertTrue(check_password('', blank_encoded))
|
||||||
self.assertFalse(check_password(' ', blank_encoded))
|
self.assertFalse(check_password(' ', blank_encoded))
|
||||||
|
@ -523,15 +523,15 @@ class TestUtilsHashPassArgon2(SimpleTestCase):
|
||||||
|
|
||||||
def test_argon2_upgrade(self):
|
def test_argon2_upgrade(self):
|
||||||
self._test_argon2_upgrade('time_cost', 'time cost', 1)
|
self._test_argon2_upgrade('time_cost', 'time cost', 1)
|
||||||
self._test_argon2_upgrade('memory_cost', 'memory cost', 16)
|
self._test_argon2_upgrade('memory_cost', 'memory cost', 64)
|
||||||
self._test_argon2_upgrade('parallelism', 'parallelism', 1)
|
self._test_argon2_upgrade('parallelism', 'parallelism', 1)
|
||||||
|
|
||||||
def test_argon2_version_upgrade(self):
|
def test_argon2_version_upgrade(self):
|
||||||
hasher = get_hasher('argon2')
|
hasher = get_hasher('argon2')
|
||||||
state = {'upgraded': False}
|
state = {'upgraded': False}
|
||||||
encoded = (
|
encoded = (
|
||||||
'argon2$argon2i$m=8,t=1,p=1$c29tZXNhbHQ$gwQOXSNhxiOxPOA0+PY10P9QFO'
|
'argon2$argon2id$v=19$m=102400,t=2,p=8$Y041dExhNkljRUUy$TMa6A8fPJh'
|
||||||
'4NAYysnqRt1GSQLE55m+2GYDt9FEjPMHhP2Cuf0nOEXXMocVrsJAtNSsKyfg'
|
'CAUXRhJXCXdw'
|
||||||
)
|
)
|
||||||
|
|
||||||
def setter(password):
|
def setter(password):
|
||||||
|
|
Loading…
Reference in New Issue