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))
|
||||
|
||||
|
||||
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):
|
||||
|
|
Loading…
Reference in New Issue