summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/auth/hashers.py5
-rw-r--r--tests/auth_tests/test_hashers.py10
2 files changed, 14 insertions, 1 deletions
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index 99d3d5ff6a..0e44614fcb 100644
--- a/django/contrib/auth/hashers.py
+++ b/django/contrib/auth/hashers.py
@@ -344,7 +344,10 @@ class Argon2PasswordHasher(BasePasswordHasher):
algorithm, rest = encoded.split('$', 1)
assert algorithm == self.algorithm
params = argon2.extract_parameters('$' + rest)
- variety, *_, salt, hash = rest.split('$')
+ variety, *_, b64salt, hash = rest.split('$')
+ # Add padding.
+ b64salt += '=' * (-len(b64salt) % 4)
+ salt = base64.b64decode(b64salt).decode('latin1')
return {
'algorithm': algorithm,
'hash': hash,
diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py
index ec056660b7..55c436b993 100644
--- a/tests/auth_tests/test_hashers.py
+++ b/tests/auth_tests/test_hashers.py
@@ -526,6 +526,16 @@ class TestUtilsHashPassArgon2(SimpleTestCase):
self.assertIs(check_password('secret', encoded), True)
self.assertIs(check_password('wrong', encoded), False)
+ def test_argon2_decode(self):
+ salt = 'abcdefghijk'
+ encoded = make_password('lètmein', salt=salt, hasher='argon2')
+ hasher = get_hasher('argon2')
+ decoded = hasher.decode(encoded)
+ self.assertEqual(decoded['memory_cost'], hasher.memory_cost)
+ self.assertEqual(decoded['parallelism'], hasher.parallelism)
+ self.assertEqual(decoded['salt'], salt)
+ self.assertEqual(decoded['time_cost'], hasher.time_cost)
+
def test_argon2_upgrade(self):
self._test_argon2_upgrade('time_cost', 'time cost', 1)
self._test_argon2_upgrade('memory_cost', 'memory cost', 64)