HansPeterLoft
HansPeterLoft

Reputation: 519

AES Python - Different output than expected

I try to make a AES ecryption script for a HEX file in python, which should then be decrypted on a microcontroller. At the moment I want to encrypt a test array (hex, 16-byte), which I already did successfully on the microcontroller, but phyton seems to do something different.

I expected the 'expected' output when encrypted, but it gives me a much larger output, but the AES block size is 16 byte, so it should work. When I have a look at the size of the iv or password after unhexlify, it states 49, that seems totally wrong. What am I doing wrong here?

from base64 import b64encode, b64decode
from binascii import unhexlify

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    iv = "000102030405060708090A0B0C0D0E0F"
    password = "2b7e151628aed2a6abf7158809cf4f3c"
    msg = "6bc1bee22e409f96e93d7e117393172a"
    expected = "7649abac8119b246cee98e9b12e9197d"

    print(f"IV: {iv}")
    print(f"PWD: {password}")
    print(f"MSG: {msg}")

    # Convert Hex String to Binary
    iv = unhexlify(iv)
    password = unhexlify(password)

    # Pad to AES Block Size
    msg = pad(msg.encode(), AES.block_size)

    print(f"IV SIZE: {iv.__sizeof__()}")
    print(f"PSW SIZE: {password.__sizeof__()}")
    print(f"MSG SIZE: {msg.__sizeof__()}")

    # Encipher Text
    cipher = AES.new(password, AES.MODE_CBC, iv)
    cipher_text = cipher.encrypt(msg)

    print(cipher_text)

    # Encode Cipher_text as Base 64 and decode to String
    out = b64encode(cipher_text).decode('utf-8')
    print(f"OUT: {out}")

    # Decipher cipher text
    decipher = AES.new(password, AES.MODE_CBC, iv)
    # UnPad Based on AES Block Size
    plaintext = unpad(decipher.decrypt(b64decode(out)), AES.block_size).decode('utf-8')
    print(f'PT: {plaintext}')

Edit: When I use len(IV) instead of size, it gives the correct length. The problem is still, that the message length is somehow 48-bytes, although the AES.block_size is 16 bytes

Upvotes: 1

Views: 390

Answers (1)

Topaco
Topaco

Reputation: 49460

The expected value for the ciphertext is produced when 1st the plaintext is not padded (the padding is not necessary because the length of the plaintext satisfies the length criterion, according to which the length must be an integer multiple of the blocksize, 16 bytes for AES), 2nd the message is hex decoded and 3rd the ciphertext is hex encoded.

I.e. you have to replace

msg = pad(msg.encode(), AES.block_size)

with

msg = unhexlify(msg)

and hex encode the ciphertext for the output (to get the expected value):

print(hexlify(cipher_text).decode('utf-8'))

Similarly, no unpadding may be performed during decryption and the message must be hex encoded and not UTF-8 decoded.

I.e. you have to replace

plaintext = unpad(decipher.decrypt(b64decode(out)), AES.block_size).decode('utf-8')

with

plaintext = hexlify(decipher.decrypt(b64decode(out))).decode('utf-8') 

Regarding the length, you have already recognized that __sizeof__() is the wrong function and that len() should be used.

Upvotes: 1

Related Questions