I am struggling with encrypting a string in python and decrypting the result in PHP. Here is what I do:
from Crypto.Cipher import AES #pycryptodome
from base64 import b64encode,b64decode
plainData = 'SimpleTest123456'
secretKey = '12345678901234567890123456789012'
plainDataPadded = (plainData + ((AES.block_size - len(plainData)) % AES.block_size) * '\0') # AES.block_size: 16
iv = base64.b64decode(b'4HlDPfgsSe3eayaeNF4hpg==')
cipher = AES.new(bytes(secretKey, 'utf-8'), AES.MODE_CBC, iv)
plainDataPadded = plainDataPadded.encode()
encryptedData= cipher.encrypt(plainDataPadded)
print('Encrypted-Python: ',base64.b64encode(encryptedData))
NOTE: In real life I would generate random bytes for the secret key and IV, but here I want to have a repeatable situation for testing purposes.
The result is: Encrypted-Python: b'SdjLXWi+A7ZtCkReXnDU4g=='
I use the following code in PHP:
$encryptedData = base64_decode("SdjLXWi+A7ZtCkReXnDU4g==");
$secretKey = "12345678901234567890123456789012";
$iv = base64_decode("4HlDPfgsSe3eayaeNF4hpg==");
$cipherType = "AES-256-CBC";
$plainText = openssl_decrypt($encryptedData, $cipherType, $secretKey, OPENSSL_RAW_DATA, $iv);
$plainText = utf8_decode($plainText);
echo "\n plainText:$plainText\n";
THis decryption fails ($painText is empty). What am I doing wrong?
I also tested to encrypt the same string in PHP:
$plainData = "SimpleTest123456";
$secretKey = "12345678901234567890123456789012";
$AESblocksize = 16;
if (strlen($plainData) % $AESblocksize) {
$plainData = str_pad($plainData,(($AESblocksize - len($plainData)) % $AESblocksize), "\0");
} // end if
$iv = base64_decode("4HlDPfgsSe3eayaeNF4hpg==");
$cipherType = "AES-256-CBC";
$encryptedData = openssl_encrypt($plainData, $cipherType, $secretKey, OPENSSL_RAW_DATA, $iv);
$encryptedData = base64_encode($encryptedData);
echo "Encrypted-PHP: ".$encryptedData;
Result: Encrypted-PHP: SdjLXWi+A7ZtCkReXnDU4rw8JlCaywDX+wWVubjQ54Q=
This is different from the encryption in python: The beginning is the same, but the PHP result is longer:
Encrypted-Python: b'SdjLXWi+A7ZtCkReXnDU4g=='
vs
Encrypted-PHP: SdjLXWi+A7ZtCkReXnDU4rw8JlCaywDX+wWVubjQ54Q=
Who can help me?
Thanks so much!!!
Crypto.Util.Padding.Crypto.Util.Padding#pad()requires the already encoded data, so that this issue is solved as well.utf8_decode(). PHP strings have no internal encoding, and all this does is force an encoding conversion from UTF8 to ISO8859-1 which will likely corrupt your data.