0

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!!!

5
  • 1
    The paddings are different. Your Python padding seems to use zero padding, PHP/openssl applies PKCS#7 padding. Note that PyCryptodome supports PKCS#7 s. Crypto.Util.Padding. Commented Aug 30, 2024 at 14:36
  • Not sure if it's related, but padding before encoding will break sooner or later, as the econded data may have a different length. Commented Aug 30, 2024 at 14:37
  • 1
    Crypto.Util.Padding#pad() requires the already encoded data, so that this issue is solved as well. Commented Aug 30, 2024 at 14:44
  • The hint about correcting the padding did the job! It now works. Thanks so much for your prompt help! Commented Aug 30, 2024 at 18:01
  • Do not use 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. Commented Aug 30, 2024 at 18:41

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.