More secure comparison of HMAC strings
To avoid timing attacks. The implementation of SecureCompareStrings is pulled directly from python 3.4 sources.
This commit is contained in:
parent
b56858d2b0
commit
ccf0a2ed4d
@ -215,10 +215,33 @@ def SafePopen( *args, **kwargs ):
|
|||||||
|
|
||||||
|
|
||||||
def ContentHexHmacValid( content, hmac, hmac_secret ):
|
def ContentHexHmacValid( content, hmac, hmac_secret ):
|
||||||
return hmac == CreateHexHmac( content, hmac_secret )
|
return SecureCompareStrings( CreateHexHmac( content, hmac_secret ), hmac )
|
||||||
|
|
||||||
|
|
||||||
def CreateHexHmac( content, hmac_secret ):
|
def CreateHexHmac( content, hmac_secret ):
|
||||||
return hmac.new( hmac_secret,
|
return hmac.new( hmac_secret,
|
||||||
msg = content,
|
msg = content,
|
||||||
digestmod = hashlib.sha256 ).hexdigest()
|
digestmod = hashlib.sha256 ).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
# This is the compare_digest function from python 3.4, adapted for 2.7:
|
||||||
|
# http://hg.python.org/cpython/file/460407f35aa9/Lib/hmac.py#l16
|
||||||
|
def SecureCompareStrings( 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, str ) and isinstance( b, str ) ):
|
||||||
|
raise TypeError( "inputs must be str 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
|
||||||
|
for x, y in zip( a, b ):
|
||||||
|
result |= ord( x ) ^ ord( y )
|
||||||
|
return result == 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user