diff options
| author | Claude Paroz <claude@2xlibre.net> | 2020-01-08 16:27:26 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-01-27 12:42:21 +0100 |
| commit | 50cf183d219face91822c75fa0a15fe2fe3cb32d (patch) | |
| tree | 56339297b6fd0a7339b9cc749648e7677fec2644 /django/utils/crypto.py | |
| parent | c00b863ac6e9f6dfb295d4fc5291726a1112c080 (diff) | |
Refs #27468 -- Added algorithm parameter to django.utils.crypto.salted_hmac().
Diffstat (limited to 'django/utils/crypto.py')
| -rw-r--r-- | django/utils/crypto.py | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/django/utils/crypto.py b/django/utils/crypto.py index 4ec1cfcf77..edeb336f34 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -9,10 +9,16 @@ from django.conf import settings from django.utils.encoding import force_bytes -def salted_hmac(key_salt, value, secret=None): +class InvalidAlgorithm(ValueError): + """Algorithm is not supported by hashlib.""" + pass + + +def salted_hmac(key_salt, value, secret=None, *, algorithm='sha1'): """ - Return the HMAC-SHA1 of 'value', using a key generated from key_salt and a - secret (which defaults to settings.SECRET_KEY). + Return the HMAC of 'value', using a key generated from key_salt and a + secret (which defaults to settings.SECRET_KEY). Default algorithm is SHA1, + but any algorithm name supported by hashlib.new() can be passed. A different key_salt should be passed in for every application of HMAC. """ @@ -21,16 +27,21 @@ def salted_hmac(key_salt, value, secret=None): key_salt = force_bytes(key_salt) secret = force_bytes(secret) - + try: + hasher = getattr(hashlib, algorithm) + except AttributeError as e: + raise InvalidAlgorithm( + '%r is not an algorithm accepted by the hashlib module.' + % algorithm + ) from e # We need to generate a derived key from our base key. We can do this by - # passing the key_salt and our base key through a pseudo-random function and - # SHA1 works nicely. - key = hashlib.sha1(key_salt + secret).digest() + # passing the key_salt and our base key through a pseudo-random function. + key = hasher(key_salt + secret).digest() # If len(key_salt + secret) > block size of the hash algorithm, the above # line is redundant and could be replaced by key = key_salt + secret, since # the hmac module does the same thing for keys longer than the block size. # However, we need to ensure that we *always* do this. - return hmac.new(key, msg=force_bytes(value), digestmod=hashlib.sha1) + return hmac.new(key, msg=force_bytes(value), digestmod=hasher) def get_random_string(length=12, |
