使用phpseclibphp 7替换不推荐使用的MCRYPT_RIJNDAELphp 5时,如何获得完全解密?

问题描述

我必须将脚本从PHP 5.6升级到7.4,但是我需要解密先前用MCRYPT_RIJNDAEL_256加密的数据(不建议使用)。我尝试使用phpseclib - Github(基于此SO answer),但是结果不完整(奇怪的字符)。如何获得正确的删除数据?

例如:

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

PHP 5.6加密:

$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解密=>确定:

$dec_old = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256,base64_decode($enc_old),md5(md5($key))),"\0");

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

使用PHPseclib进行PHP 7.4解密:

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 parametermd5(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)) );

使解密工作正常。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...