pythoncryptographyaespycryptodome

pycryptodome decryption (aes-128 cbc) is yielding incorrect result


I have simple code to encrypt and decrypt as follows...

(1) To encrypt:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Hash import SHA256 as sha256

def sha(text):
    _sha = sha256.new(text)
    return _sha.hexdigest()
    
key = '1234'
print('Key length:', len(key))
block_size = 16

plain_text = "The quick brown fox jumped over the lazy dog"
print('Plain text length:', len(plain_text))

akey = pad(key.encode(), block_size)
print('akey length', len(akey))

pt_encoded = plain_text.encode()

cipher = AES.new(akey, AES.MODE_CBC)
payload = pad(pt_encoded, block_size)
print('sha payload:', sha(payload))

encrypted = cipher.encrypt(payload)

# print(encrypted)

print('Encrypted sha:', sha(encrypted))

with open('data.bin', 'wb') as f:
    f.write(encrypted)

(2) To Decrypt

cipher2 = AES.new(akey, AES.MODE_CBC)

with open('data.bin', 'rb') as f:
    data = f.read()
    
print('file contents sha:', sha(data))
decrypted = cipher2.decrypt(data)
print('decrypted sha:', sha(decrypted))

plain = unpad(decrypted, block_size)

print('Plain text:', plain.decode())

Entire code and error in the gist: https://gist.github.com/deostroll/be4c6768b1e73b72fb0313e90345a0dd

The observation is that after obtaining the decrypted contents and trying to decode, I get the following error:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa8 in position 1: invalid start byte

Am I correctly trying to do the encryption/decryption?


Solution

  • You need to use the same IV for decryption that you used for encryption.

    For encryption you can try:

    with open('data.bin', 'wb') as file:
        file.write(cipher.iv + encrypted)
    

    For decryption you can do:

    with open('data.bin', 'rb') as file:
        data = file.read()
    
    iv, data = data[:16], data[16:]
    cipher2 = AES.new(akey, AES.MODE_CBC, iv=iv)
    

    This should work.