2

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?

Muppet
  • 5,767
  • 6
  • 29
  • 39

1 Answers1

4

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
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • Thanks for the answer. However, when I run your code it doesn't seem to be matching the openssl output that my original code generates: `ukMTwxkz19qVPiwU8xa/YM9ENqklbZtB86AaVPULHLE=` - do you know why that is? – Muppet Mar 30 '21 at 02:29
  • Yes. You specified ```-base64``` as a flag (apologies for missing it when I initially made the solution). You can ```from base64 import b64encode``` and instead of hexlifying the cipher_text, you can ```b64encode(cipher_text).decode('utf-8')``` to get your expected string. *I've updated my solution to reflect this change. – Henry Ecker Mar 30 '21 at 02:48