Search code examples
pythonopensslcryptographyaespycrypto

AES-128 CBC encryption in python


I am trying to get rid of the openssl call below and replace it with pure python code.

import os
    
iv = "7bde5a0f3f39fd658efc45de143cbc94"
password = "3e83b13d99bf0de6c6bde5ac5ca4ae68"
msg = "this is a message"

out = os.popen(f'printf "{msg}" | openssl aes-128-cbc -base64 -K {password} -iv {iv}').read()

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

yields:

IV: 7bde5a0f3f39fd658efc45de143cbc94
PWD: 3e83b13d99bf0de6c6bde5ac5ca4ae68
MSG: this is a message
OUT: ukMTwxkz19qVPiwU8xa/YM9ENqklbZtB86AaVPULHLE=

Between the 3 different libraries that people seem to suggest and various other code excerpts that don't seem to work anymore, I haven't been able to replicate it in pure python reliably. Would anyone have a working code example for the above?


Solution

  • With Python3 you can use PyCryptodome, binascii and base64.

    from base64 import b64encode, b64decode
    from binascii import unhexlify
    
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad, unpad
    
    iv = "7bde5a0f3f39fd658efc45de143cbc94"
    password = "3e83b13d99bf0de6c6bde5ac5ca4ae68"
    msg = "this is a message"
    
    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)
    # Encipher Text
    cipher = AES.new(password, AES.MODE_CBC, iv)
    cipher_text = cipher.encrypt(msg)
    
    # 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}')
    

    You can see more:

    1. AES-128 CBC decryption in Python
    2. Python Encrypting with PyCrypto AES