AES in Python with OpenSSL outputIn CBC we add salt and a passphrase to produce an IV. In the following we create a format which is used with OpenSSL: |
Outline
In this case we use Python and pass the plaintext, passphrase and salt. If we use OpenSSL we get:
echo -n Hello | openssl enc -aes-256-cbc -pass pass:"qwerty" -e -base64 -S 241fa86763b85341 U2FsdGVkX18kH6hnY7hTQZAGxV2faF01w6uhO+X6+9Q=
A Python program which produces the same output is:
# https://asecuritysite.com/encryption/aes_python from Crypto.Cipher import AES import sys import base64 import Padding plaintext='Hello' key='qwerty' salt='241fa86763b85341' if (len(sys.argv)>1): plaintext=str(sys.argv[1]) if (len(sys.argv)>2): key=str(sys.argv[2]) if (len(sys.argv)>3): salt=str(sys.argv[3]) def get_key_and_iv(password, salt, klen=32, ilen=16, msgdgst='md5'): mdf = getattr(__import__('hashlib', fromlist=[msgdgst]), msgdgst) password = password.encode('ascii', 'ignore') # convert to ASCII salt = bytearray.fromhex(salt) # convert to ASCII try: maxlen = klen + ilen keyiv = mdf((password + salt)).digest() tmp = [keyiv] while len(tmp) < maxlen: tmp.append( mdf(tmp[-1] + password + salt).digest() ) keyiv += tmp[-1] # append the last byte key = keyiv[:klen] iv = keyiv[klen:klen+ilen] return key, iv except UnicodeDecodeError: return None, None def encrypt(plaintext,key, mode,salt): key,iv=get_key_and_iv(key,salt) encobj = AES.new(key,mode,iv) return(encobj.encrypt(plaintext.encode())) def decrypt(ciphertext,key, mode,salt): key,iv=get_key_and_iv(key,salt) encobj = AES.new(key,mode,iv) return(encobj.decrypt(ciphertext)) print ("Plaintext:\t",plaintext) print ("Passphrase:\t",key) print ("Salt:\t\t",salt) plaintext = Padding.appendPadding(plaintext,mode='CMS') ciphertext = encrypt(plaintext,key,AES.MODE_CBC,salt) ctext = b'Salted__' + bytearray.fromhex(salt) + ciphertext print ("\nCipher (CBC) - Base64:\t",base64.b64encode(bytearray(ctext)).decode()) print ("\nCipher (CBC) - Hex:\t",ctext.hex()) print ("Cipher in binary:\t",ctext) plaintext = decrypt(ciphertext,key,AES.MODE_CBC,salt) print ("\nDecrypted (Before unpad):\t",plaintext) plaintext = Padding.removePadding(plaintext.decode(),mode='CMS') print ("\nDecrypted:\t"+plaintext)
A sample run is:
Plaintext: Hello Passphrase: qwerty Salt: 241fa86763b85341 Cipher (CBC) - Base64: U2FsdGVkX18kH6hnY7hTQZAGxV2faF01w6uhO+X6+9Q= Cipher (CBC) - Hex: 53616c7465645f5f241fa86763b853419006c55d9f685d35c3aba13be5fafbd4 Cipher in binary: Salted__$¨gc¸SAÅ]Ÿh]5ë¡;åúûÔ Decrypted: Hello
In hex, "53616c7465645f5f" is "Salted__"