I have to upgrade a script from php 5.6 to 7.4, but I need to decrypt data previosly encrypted with MCRYPT_RIJNDAEL_256
(deprecated). I try to use phpseclib – Github (based on this SO answer), but I’m getting an incomplete result (strange chars). How can I get the correct decrtypted data?
For example:
$key = "0123456789abcdefghijklmn"; // len = 24 $data = "ABC123 abc123 ABC123 abc123 ABC123 abc123 ABC123 abc123";
PHP 5.6 encryption:
$enc_old = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $data, MCRYPT_MODE_CBC, md5(md5($key)))); echo $enc_old; // eOIZd9ND59vfjx6A5fteiFQWgwYFawPccCieAxD1Ir+xJnutpdsc7b6ELNArNPLSghfdVteO0WM4lcfTQToR8w==
PHP 5.6 decryption => OK:
$dec_old = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($enc_old), MCRYPT_MODE_CBC, md5(md5($key))), ""); echo $dec_old; // ABC123 abc123 ABC123 abc123 ABC123 abc123 ABC123 abc123
PHP 7.4 decryption with phpseclib
:
require "vendor/autoload.php"; $rijndael = new phpseclibCryptRijndael(phpseclibCryptRijndael::MODE_CBC); $rijndael->setKey( md5($key) ); $rijndael->setKeyLength(256); $rijndael->disablePadding(); $rijndael->setBlockLength(256); $dec_new = $rijndael->decrypt( base64_decode($enc_old) ); echo $dec_new; // ttRFXQZVr {PFTVTPs t23 abc123 ABC123 abc123
Basically, the first part of the data seems corrupted. But the rest of the data is ok. How can I decrypt the entire data correctly?
EDIT:
As pointed out by @Michael Fehr , in the original mcrypt_encrypt
version an IV
was set (i.e. the last parameter: md5(md5($key)
) ), that had to be added in the decryption. Thus, I added this line:
$rijndael->setIV( md5(md5($key)) );
and now the entire data is decrypted correctly.
Advertisement
Answer
In your PHP 5.6 encryption you code:
$enc_old = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $data, MCRYPT_MODE_CBC, md5(md5($key))));
where the last md5(md5($key)) is for the initialization vector.
I’m missing the setting of the IV in your (new) PHP 7.4 decryption method – as you are using AES in the mode CBC and that requires an IV.
As you found by yourself you should add the line
$rijndael->setIV( md5(md5($key)) );
to get your decryption working.