0

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))), "\0");

echo $dec_old;
// ABC123 abc123 ABC123 abc123 ABC123 abc123 ABC123 abc123

PHP 7.4 decryption with phpseclib:

require "vendor/autoload.php";

$rijndael = new \phpseclib\Crypt\Rijndael(\phpseclib\Crypt\Rijndael::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.

verjas
  • 1,793
  • 1
  • 15
  • 18
  • 1
    Using "old" PHP 5.6 you hash the $key two times with md5 for the value of initialization vector, the "new" 7.4 decryption does not set the IV ? – Michael Fehr Aug 26 '20 at 10:36
  • Thank you! I added this line: $rijndael->setIV( md5(md5($key)) ); and now the decryption is full. I will test it on a long real-data file, to see if that makes it right. Could you post it as an answer with some explanation why that changes everything? To select it as the correct answer. – verjas Aug 26 '20 at 10:56

1 Answers1

1

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.

Michael Fehr
  • 5,827
  • 2
  • 19
  • 40