Search code examples
pythonpython-3.xaespycryptopycryptodome

PyCryptoDome : AES-256 giving different output with same key & data


The following code produces a different ciphertext every time I execute it, which shouldn't happen since the key & data being passed is same for every execution.

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode, b64decode

key = '/I02fMuSSvnouuu+/vyyD7NuSEVDB/0gte/z50dM0b4='
data = 'hello world!'

cipher = AES.new(b64decode(key), AES.MODE_CBC)
padded_data = pad(data.encode(), cipher.block_size)
print(b64encode(padded_data))
# b'aGVsbG8gd29ybGQhBAQEBA=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'rEHH0MWIWCWUldjYBco9TA=='
ciphertext = cipher.encrypt(padded_data)
print(b64encode(ciphertext))
# b'FTpLrkZttDxMlpre3Kq8qQ=='

I am actually trying to replicate a sample PHP code to Python, the PHP code gives the same output and my Python code gives different outputs, none of which match the PHP one.

Python version 3.6.x
PyCryptoDome version 3.4.7


Solution

  • I forgot to pass the iv parameter while creating the cipher object.

    It should be something like -

    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    

    And yeah, as correctly pointed out by Rawing, repeatedly using the same cipher object to encrypt will give different results, but it will always give same output if you reconstruct the cipher object.

    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    padded_data = pad(data.encode(), cipher.block_size)
    print(b64encode(padded_data))
    # b'aGVsbG8gd29ybGQhBAQEBA=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'8G0KL2UiCv7Uo+pKMm9G+A=='
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'tBXcf/Nf6MtxM1ulzNnIlw=='
    
    
    cipher = AES.new(b64decode(key), AES.MODE_CBC, iv=b'0123456789abcdef')
    padded_data = pad(data.encode(), cipher.block_size)
    ciphertext = cipher.encrypt(padded_data)
    print(b64encode(ciphertext))
    # b'8G0KL2UiCv7Uo+pKMm9G+A=='