使用 phpseclib (php 7) 替换已弃用的 MCRYPT_RIJNDAEL (php 5) 时如何获得完整解密?

How to get complete decryption when using phpseclib (php 7) to replace deprecated MCRYPT_RIJNDAEL (php 5)?

我必须将脚本从 php 5.6 升级到 7.4,但我需要解密之前使用 MCRYPT_RIJNDAEL_256(已弃用)加密的数据。我尝试使用 phpseclib - Github (based on this ),但得到的结果不完整(奇怪的字符)。如何获得正确的解密数据?

例如:

$key = "0123456789abcdefghijklmn"; // len = 24
$data = "ABC123 abc123 ABC123 abc123 ABC123 abc123 ABC123 abc123";

PHP5.6加密:

$enc_old = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $data, MCRYPT_MODE_CBC, md5(md5($key))));
echo $enc_old;
// eOIZd9ND59vfjx6A5fteiFQWgwYFawPccCieAxD1Ir+xJnutpdsc7b6ELNArNPLSghfdVteO0WM4lcfTQToR8w==

PHP5.6解密=>OK:

$dec_old = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($enc_old), MCRYPT_MODE_CBC, md5(md5($key))), "[=15=]");

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

PHP 7.4解密用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

基本上,数据的第一部分似乎已损坏。但其余数据没问题。 如何正确解密整个数据?

编辑: 正如@Michael Fehr 指出的那样,在原始 mcrypt_encrypt 版本中设置了 IV (即 the last parameter: md5(md5($key)) ),必须在解密中添加。因此,我添加了这一行:

$rijndael->setIV( md5(md5($key)) );

现在整个数据 已正确解密

在你的 PHP 5.6 加密中你代码:

$enc_old = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $data, MCRYPT_MODE_CBC, md5(md5($key))));

其中最后一个 md5(md5($key)) 用于初始化向量。

我在您的(新)PHP 7.4 解密方法中缺少 IV 的设置 - 因为您在 CBC 模式下使用 AES 并且需要 IV。

正如您自己发现的那样,您应该添加行

$rijndael->setIV( md5(md5($key)) );

让你的解密工作。