Skip to content

Instantly share code, notes, and snippets.

@eoli3n
Last active May 28, 2024 02:47
Show Gist options
  • Save eoli3n/d6d862feb71102588867516f3b34fef1 to your computer and use it in GitHub Desktop.
Save eoli3n/d6d862feb71102588867516f3b34fef1 to your computer and use it in GitHub Desktop.
Encrypt - Decrypt AES from/to Python PyCryptodome from/to PHP openssl
<?php
// use to generate key : 'openssl rand -hex 32'
function my_encrypt($data, $passphrase) {
$secret_key = hex2bin($passphrase);
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encrypted_64 = openssl_encrypt($data, 'aes-256-cbc', $secret_key, 0, $iv);
$iv_64 = base64_encode($iv);
$json = new stdClass();
$json->iv = $iv_64;
$json->data = $encrypted_64;
return base64_encode(json_encode($json));
}
function my_decrypt($data, $passphrase) {
$secret_key = hex2bin($passphrase);
$json = json_decode(base64_decode($data));
$iv = base64_decode($json->{'iv'});
$encrypted_64 = $json->{'data'};
$data_encrypted = base64_decode($encrypted_64);
$decrypted = openssl_decrypt($data_encrypted, 'aes-256-cbc', $secret_key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
#!/usr/bin/env python3
# pip install pycryptodome
import json
import binascii
from Crypto.Cipher import AES
from Crypto import Random
import base64
def my_encrypt(data, passphrase):
"""
Encrypt using AES-256-CBC with random/shared iv
'passphrase' must be in hex, generate with 'openssl rand -hex 32'
"""
try:
key = binascii.unhexlify(passphrase)
pad = lambda s : s+chr(16-len(s)%16)*(16-len(s)%16)
iv = Random.get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted_64 = base64.b64encode(cipher.encrypt(pad(data).encode())).decode('ascii')
iv_64 = base64.b64encode(iv).decode('ascii')
json_data = {}
json_data['iv'] = iv_64
json_data['data'] = encrypted_64
clean = base64.b64encode(json.dumps(json_data).encode('ascii'))
except Exception as e:
print("Cannot encrypt datas...")
print(e)
exit(1)
return clean
def my_decrypt(data, passphrase):
"""
Decrypt using AES-256-CBC with iv
'passphrase' must be in hex, generate with 'openssl rand -hex 32'
# https://stackoverflow.com/a/54166852/11061370
"""
try:
unpad = lambda s : s[:-s[-1]]
key = binascii.unhexlify(passphrase)
encrypted = json.loads(base64.b64decode(data).decode('ascii'))
encrypted_data = base64.b64decode(encrypted['data'])
iv = base64.b64decode(encrypted['iv'])
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(encrypted_data)
clean = unpad(decrypted).decode('ascii').rstrip()
except Exception as e:
print("Cannot decrypt datas...")
print(e)
exit(1)
return clean
@mspi21
Copy link

mspi21 commented Apr 1, 2024

Security considerations

You are aware of the fact that the parameters that you're referring to as "passphrases" are really not passphrases, but cryptographic keys, which have to consist of cryptographically strong random bytes, are you not?

You can generate symmetric encryption keys directly in your code (maybe via a separate function, e.g. generate_secure_encryption_key()) using the same way you're generating your initialization vectors, i.e. through Crypto.Random (or alternatively, os.urandom). The key needs to then be stored somewhere safe, e.g. a file readable only by its owner.

If you need to use a passphrase for encryption, such as the string "a quick brown fox jumps over the lazy dog", you need to use a key derivation function to transform your passphrase into a suitable key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment