summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/utils/crypto.py42
1 files changed, 23 insertions, 19 deletions
diff --git a/django/utils/crypto.py b/django/utils/crypto.py
index d02ee5351d..8bf884a72f 100644
--- a/django/utils/crypto.py
+++ b/django/utils/crypto.py
@@ -77,27 +77,31 @@ def get_random_string(length=12,
return ''.join(random.choice(allowed_chars) for i in range(length))
-def constant_time_compare(val1, val2):
- """
- Returns True if the two strings are equal, False otherwise.
+if hasattr(hmac, "compare_digest"):
+ # Prefer the stdlib implementation, when available.
+ constant_time_compare = hmac.compare_digest
+else:
+ def constant_time_compare(val1, val2):
+ """
+ Returns True if the two strings are equal, False otherwise.
- The time taken is independent of the number of characters that match.
+ The time taken is independent of the number of characters that match.
- For the sake of simplicity, this function executes in constant time only
- when the two strings have the same length. It short-circuits when they
- have different lengths. Since Django only uses it to compare hashes of
- known expected length, this is acceptable.
- """
- if len(val1) != len(val2):
- return False
- result = 0
- if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
- for x, y in zip(val1, val2):
- result |= x ^ y
- else:
- for x, y in zip(val1, val2):
- result |= ord(x) ^ ord(y)
- return result == 0
+ For the sake of simplicity, this function executes in constant time only
+ when the two strings have the same length. It short-circuits when they
+ have different lengths. Since Django only uses it to compare hashes of
+ known expected length, this is acceptable.
+ """
+ if len(val1) != len(val2):
+ return False
+ result = 0
+ if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
+ for x, y in zip(val1, val2):
+ result |= x ^ y
+ else:
+ for x, y in zip(val1, val2):
+ result |= ord(x) ^ ord(y)
+ return result == 0
def _bin_to_long(x):