Merge pull request #2600 from alex/builtin-constant-time-compare
Use the stdlib's compare_digest for constant time comparisons when available
This commit is contained in:
commit
03401701f3
|
@ -77,27 +77,31 @@ def get_random_string(length=12,
|
||||||
return ''.join(random.choice(allowed_chars) for i in range(length))
|
return ''.join(random.choice(allowed_chars) for i in range(length))
|
||||||
|
|
||||||
|
|
||||||
def constant_time_compare(val1, val2):
|
if hasattr(hmac, "compare_digest"):
|
||||||
"""
|
# Prefer the stdlib implementation, when available.
|
||||||
Returns True if the two strings are equal, False otherwise.
|
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
|
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
|
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
|
have different lengths. Since Django only uses it to compare hashes of
|
||||||
known expected length, this is acceptable.
|
known expected length, this is acceptable.
|
||||||
"""
|
"""
|
||||||
if len(val1) != len(val2):
|
if len(val1) != len(val2):
|
||||||
return False
|
return False
|
||||||
result = 0
|
result = 0
|
||||||
if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
|
if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
|
||||||
for x, y in zip(val1, val2):
|
for x, y in zip(val1, val2):
|
||||||
result |= x ^ y
|
result |= x ^ y
|
||||||
else:
|
else:
|
||||||
for x, y in zip(val1, val2):
|
for x, y in zip(val1, val2):
|
||||||
result |= ord(x) ^ ord(y)
|
result |= ord(x) ^ ord(y)
|
||||||
return result == 0
|
return result == 0
|
||||||
|
|
||||||
|
|
||||||
def _bin_to_long(x):
|
def _bin_to_long(x):
|
||||||
|
|
Loading…
Reference in New Issue