Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.5.x] Fixed #18144 -- Added backwards compatibility with old unsalt…

…ed MD5 passwords

Thanks apreobrazhensky at gmail.com for the report.
Backport of 63d6a50 from master.
  • Loading branch information...
commit c39be8b836282c1060e64dc17c6cb8184c14cf0b 1 parent fd61ce9
@claudep claudep authored
View
5 django/contrib/auth/hashers.py
@@ -132,7 +132,8 @@ def identify_hasher(encoded):
get_hasher() to return hasher. Raises ValueError if
algorithm cannot be identified, or if hasher is not loaded.
"""
- if len(encoded) == 32 and '$' not in encoded:
+ if ((len(encoded) == 32 and '$' not in encoded) or
+ len(encoded) == 37 and encoded.startswith('md5$$')):
algorithm = 'unsalted_md5'
else:
algorithm = encoded.split('$', 1)[0]
@@ -372,6 +373,8 @@ def encode(self, password, salt):
return hashlib.md5(force_bytes(password)).hexdigest()
def verify(self, password, encoded):
+ if len(encoded) == 37 and encoded.startswith('md5$$'):
+ encoded = encoded[5:]
encoded_2 = self.encode(password, '')
return constant_time_compare(encoded, encoded_2)
View
5 django/contrib/auth/tests/hashers.py
@@ -66,6 +66,11 @@ def test_unsalted_md5(self):
self.assertTrue(check_password('lètmein', encoded))
self.assertFalse(check_password('lètmeinz', encoded))
self.assertEqual(identify_hasher(encoded).algorithm, "unsalted_md5")
+ # Alternate unsalted syntax
+ alt_encoded = "md5$$%s" % encoded
+ self.assertTrue(is_password_usable(alt_encoded))
+ self.assertTrue(check_password('lètmein', alt_encoded))
+ self.assertFalse(check_password('lètmeinz', alt_encoded))
@skipUnless(crypt, "no crypt module to generate password.")
def test_crypt(self):
Please sign in to comment.
Something went wrong with that request. Please try again.