mirror of
https://github.com/python/cpython.git
synced 2025-11-25 21:11:09 +00:00
Issue #15061: Don't oversell the capabilities of the new non-shortcircuiting comparison function in hmac
This commit is contained in:
parent
307693a8bb
commit
807770ec1b
4 changed files with 72 additions and 56 deletions
26
Lib/hmac.py
26
Lib/hmac.py
|
|
@ -13,24 +13,24 @@ trans_36 = bytes((x ^ 0x36) for x in range(256))
|
|||
digest_size = None
|
||||
|
||||
|
||||
def secure_compare(a, b):
|
||||
"""Returns the equivalent of 'a == b', but using a time-independent
|
||||
comparison method to prevent timing attacks."""
|
||||
if not ((isinstance(a, str) and isinstance(b, str)) or
|
||||
(isinstance(a, bytes) and isinstance(b, bytes))):
|
||||
raise TypeError("inputs must be strings or bytes")
|
||||
def compare_digest(a, b):
|
||||
"""Returns the equivalent of 'a == b', but avoids content based short
|
||||
circuiting to reduce the vulnerability to timing attacks."""
|
||||
# Consistent timing matters more here than data type flexibility
|
||||
if not (isinstance(a, bytes) and isinstance(b, bytes)):
|
||||
raise TypeError("inputs must be bytes instances")
|
||||
|
||||
# We assume the length of the expected digest is public knowledge,
|
||||
# thus this early return isn't leaking anything an attacker wouldn't
|
||||
# already know
|
||||
if len(a) != len(b):
|
||||
return False
|
||||
|
||||
# We assume that integers in the bytes range are all cached,
|
||||
# thus timing shouldn't vary much due to integer object creation
|
||||
result = 0
|
||||
if isinstance(a, bytes):
|
||||
for x, y in zip(a, b):
|
||||
result |= x ^ y
|
||||
else:
|
||||
for x, y in zip(a, b):
|
||||
result |= ord(x) ^ ord(y)
|
||||
|
||||
for x, y in zip(a, b):
|
||||
result |= x ^ y
|
||||
return result == 0
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue