mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #18144 -- Added backwards compatibility with old unsalted MD5 passwords
Thanks apreobrazhensky at gmail.com for the report.
This commit is contained in:
		| @@ -132,7 +132,8 @@ def identify_hasher(encoded): | |||||||
|     get_hasher() to return hasher. Raises ValueError if |     get_hasher() to return hasher. Raises ValueError if | ||||||
|     algorithm cannot be identified, or if hasher is not loaded. |     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' |         algorithm = 'unsalted_md5' | ||||||
|     else: |     else: | ||||||
|         algorithm = encoded.split('$', 1)[0] |         algorithm = encoded.split('$', 1)[0] | ||||||
| @@ -372,6 +373,8 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher): | |||||||
|         return hashlib.md5(force_bytes(password)).hexdigest() |         return hashlib.md5(force_bytes(password)).hexdigest() | ||||||
|  |  | ||||||
|     def verify(self, password, encoded): |     def verify(self, password, encoded): | ||||||
|  |         if len(encoded) == 37 and encoded.startswith('md5$$'): | ||||||
|  |             encoded = encoded[5:] | ||||||
|         encoded_2 = self.encode(password, '') |         encoded_2 = self.encode(password, '') | ||||||
|         return constant_time_compare(encoded, encoded_2) |         return constant_time_compare(encoded, encoded_2) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -66,6 +66,11 @@ class TestUtilsHashPass(unittest.TestCase): | |||||||
|         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, "unsalted_md5") |         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.") |     @skipUnless(crypt, "no crypt module to generate password.") | ||||||
|     def test_crypt(self): |     def test_crypt(self): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user