never use secret key as an initialization vector

This commit is contained in:
Marcin Wielgoszewski
2013-01-27 12:47:19 -05:00
parent 76b035b800
commit d16b5899e8
+13 -5
View File
@@ -49,7 +49,13 @@ except ImportError:
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):
""" 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:
dump = zlib.compress(dump, compression_level)
key = pad(encryption_key[:32])
cipher = AES_new(key)
encrypted_data = base64.urlsafe_b64encode(cipher.encrypt(pad(dump)))
cipher, IV = AES_new(key)
encrypted_data = base64.urlsafe_b64encode(IV + cipher.encrypt(pad(dump)))
signature = hmac.new(hash_key, encrypted_data).hexdigest()
return signature + ':' + encrypted_data
@@ -147,9 +153,11 @@ def secure_loads(data, encryption_key, hash_key=None, compression_level=None):
if not compare(signature, actual_signature):
return None
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:
data = cipher.decrypt(base64.urlsafe_b64decode(encrypted_data))
data = cipher.decrypt(encrypted_data)
data = data.rstrip(' ')
if compression_level:
data = zlib.decompress(data)