Merge pull request #58 from mwielgoszewski/master
Cryptographic vulnerabilities: Key as IV, insecure HMAC comparison
This commit is contained in:
+14
-6
@@ -49,7 +49,13 @@ except ImportError:
|
|||||||
|
|
||||||
logger = logging.getLogger("web2py")
|
logger = logging.getLogger("web2py")
|
||||||
|
|
||||||
AES_new = lambda key: AES.new(key, AES.MODE_CBC, IV=key[:16])
|
def AES_new(key, IV=None):
|
||||||
|
""" Returns an AES cipher object and random IV if None specified """
|
||||||
|
if IV is None:
|
||||||
|
IV = fast_urandom16()
|
||||||
|
|
||||||
|
return AES.new(key, AES.MODE_CBC, IV), IV
|
||||||
|
|
||||||
|
|
||||||
def compare(a, b):
|
def compare(a, b):
|
||||||
""" compares two strings and not vulnerable to timing attacks """
|
""" compares two strings and not vulnerable to timing attacks """
|
||||||
@@ -131,8 +137,8 @@ def secure_dumps(data, encryption_key, hash_key=None, compression_level=None):
|
|||||||
if compression_level:
|
if compression_level:
|
||||||
dump = zlib.compress(dump, compression_level)
|
dump = zlib.compress(dump, compression_level)
|
||||||
key = pad(encryption_key[:32])
|
key = pad(encryption_key[:32])
|
||||||
cipher = AES_new(key)
|
cipher, IV = AES_new(key)
|
||||||
encrypted_data = base64.urlsafe_b64encode(cipher.encrypt(pad(dump)))
|
encrypted_data = base64.urlsafe_b64encode(IV + cipher.encrypt(pad(dump)))
|
||||||
signature = hmac.new(hash_key, encrypted_data).hexdigest()
|
signature = hmac.new(hash_key, encrypted_data).hexdigest()
|
||||||
return signature + ':' + encrypted_data
|
return signature + ':' + encrypted_data
|
||||||
|
|
||||||
@@ -144,12 +150,14 @@ def secure_loads(data, encryption_key, hash_key=None, compression_level=None):
|
|||||||
hash_key = hashlib.sha1(encryption_key).hexdigest()
|
hash_key = hashlib.sha1(encryption_key).hexdigest()
|
||||||
signature, encrypted_data = data.split(':', 1)
|
signature, encrypted_data = data.split(':', 1)
|
||||||
actual_signature = hmac.new(hash_key, encrypted_data).hexdigest()
|
actual_signature = hmac.new(hash_key, encrypted_data).hexdigest()
|
||||||
if signature != actual_signature:
|
if not compare(signature, actual_signature):
|
||||||
return None
|
return None
|
||||||
key = pad(encryption_key[:32])
|
key = pad(encryption_key[:32])
|
||||||
cipher = AES_new(key)
|
encrypted_data = base64.urlsafe_b64decode(encrypted_data)
|
||||||
|
IV, encrypted_data = encrypted_data[:16], encrypted_data[16:]
|
||||||
|
cipher, _ = AES_new(key, IV=IV)
|
||||||
try:
|
try:
|
||||||
data = cipher.decrypt(base64.urlsafe_b64decode(encrypted_data))
|
data = cipher.decrypt(encrypted_data)
|
||||||
data = data.rstrip(' ')
|
data = data.rstrip(' ')
|
||||||
if compression_level:
|
if compression_level:
|
||||||
data = zlib.decompress(data)
|
data = zlib.decompress(data)
|
||||||
|
|||||||
Reference in New Issue
Block a user