PHP code
// php 8.1.13
$text = '1';
$key = base64_decode('3pKtqxNOolyBoJouXWwVYw==');
$iv = base64_decode('O99EDNAif90=');
$encrypted = openssl_encrypt($text, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, $iv);
$hex = strtoupper(bin2hex($encrypted));
echo $hex;
The result is FF72E6D454B84A7C
Python3.8 pycryptodome 3.20.0
import binascii
import base64
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad
key = base64.b64decode('3pKtqxNOolyBoJouXWwVYw==')
iv = base64.b64decode('O99EDNAif90=')
cipher = DES3.new(key, DES3.MODE_CBC, iv)
data = '1'
data = data.encode('utf-8')
data = pad(data, DES3.block_size)
encrypted = cipher.encrypt(data)
print(binascii.hexlify(encrypted).decode('utf-8').upper())
The result is A311743FB5D91569
Why are these two results different, and how can I make python's results consistent with PHP's?
I've tried using pycryptodome and pyDes and can't achieve the same result as PHP
The reason for the different results is that different TripleDES variants are used in both codes.
des-ede3-cbc
in the PHP code specifies 3TDEA, which requires a 24 bytes key. Since the key used is only 16 bytes in size, PHP/OpenSSL silently pads it with 0x00 values to the required size of 24 bytes.
With PyCryptodome, the key length determines the variant. Since the key is 16 bytes in size, 2TDEA is applied. For this reason the result is different.
In order to also use 3TDEA, the key must be explicitly padded in the Python code, i.e. expanded to 24 bytes with 0x00 values:
key = base64.b64decode('3pKtqxNOolyBoJouXWwVYw==') + b'\x00'*8
If this key is applied in the Python code, the result is the same as in the PHP code.