Php mcrypt_加密到openssl_加密,以及openssl_零填充问题

Php mcrypt_加密到openssl_加密,以及openssl_零填充问题,php,openssl,mcrypt,3des,php-openssl,Php,Openssl,Mcrypt,3des,Php Openssl,对于给定的$key,$message和$iv,我有一个mcrypt\u encrypt调用: $string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv); 我想将mcrypt\u encrypt调用更改为openssl\u encryptone,以证明这一点 通过使用$mode='des-ede3-cbc'或$mode='3DES'和$options=true我得到了更相似的响应,但不完全相同。有没有其

对于给定的
$key
$message
$iv
,我有一个
mcrypt\u encrypt
调用:

$string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
我想将
mcrypt\u encrypt
调用更改为
openssl\u encrypt
one,以证明这一点

通过使用
$mode='des-ede3-cbc'
$mode='3DES'
$options=true
我得到了更相似的响应,但不完全相同。有没有其他方法可以称之为完美匹配

我用lorem ipsum
$message
+
$key
组合得到这个(base64_编码),所以我开始相信一个函数或另一个函数在加密之前填充了一些消息

为mcrypt

“Y+JGMBDI7ZY3M9LJXCTB5VGU+rWvLBfjug2GLX7uo=”

用于openssl

“Y+JGMBDI7ZY3M9LJXCTB5VGU+rWvLBvte4swdttHY=”

尝试使用$options传递OPENSSL\u ZERO\u填充,但传递除1(OPENSSL\u RAW\u DATA,或true)以外的任何内容都会导致空字符串


既不使用
OPENSSL_ZERO_PADDING
也不使用
OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING
工作…:( 我使用的是“OpenSSL 1.0.2g 2016年3月1日”


已经读过q&a了,但它对我没有帮助。不是因为填充问题,但到目前为止还看不到解决方案。(第二个答案是关于向mcrypt调用添加填充,我真的想从openssl加密调用中删除填充…

mcrypt\u encrypt
使用零将消息填充到块大小。因此,您可以在原始数据的尾部添加零,然后对块进行加密


使用
OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING
应该可以工作。如果不行,那么你可以自己从解密的数据中删除PADDING。

ZERO padds输入数据,如果它不是块大小的倍数。如果数据本身有尾随零,这会导致结果不明确。显然,OPENSSL不允许你使用ZERO paddin在本例中为g,这解释了错误的返回值

您可以通过手动添加填充来避免这种情况。

这两种打印方式相同。


你永远不应该得到一个完美的匹配。这就是初始化向量的作用。每次你用相同的算法和相同的密钥加密相同的负载时,如果你想安全的话,你应该得到完全不同的输出。如果你对相同的输入得到相同的输出,你的加密就很弱。这就是加密中的IV点。一旦encrypted,您使用IV向另一方交付加密的有效负载。如果我使用相同的有效负载、相同的算法、相同的IV;我认为我应该得到相同的输出。不要介意,我应该为每个调用使用不同的IV:为两个调用使用相同的IV(mcrypt和openssl),我认为我应该得到相同的输出,对吗?我开始相信这与消息填充有关,因为输出的请求是相同的。如果所有内容都相同,那么您应该得到相同的输出,对不对。
openssl\u encrypt
的第四个参数控制填充。您可以使用
$encrypted=openssl\u encryp进行加密t($data,$alg,$key,OPENSSL\u ZERO\u PADDING,$iv)
并检查是否得到相同的输出。在,您可以阅读注释以了解如何使用第4个参数。
OPENSSL_ZERO_PADDING
不起作用,至少对我来说是这样……但是,是的-PADDING是无法得到相同结果的原因。然而,您的加密方案有太多错误的想法,您不妨用一个ne来代替它w one-请为此使用库,不要使用自己的库。现在我将了解如何进行此调用并获得与mcrypt相同的结果。感谢您对加密的评论。这既不是完整的解决方案,也不是我有权更改此代码库中所需的所有内容。我为什么要花时间呢?
OPENSSL_原始数据| OPENSSL_ZERO_PADDING
不起作用。可能是phps OPENSSL实现中的错误或其他原因?从未加密数据中删除额外字符对我不起作用。此字符串用作验证签名:我收到一个和一些数据,创建此加密数据以匹配收到的签名。我不控制l另一端的系统。修改mcrypt_uuu调用使其匹配openssl_uu对我没有帮助,我需要openssl_uuu来匹配mcrypt:)您可以自己添加零填充,然后调用openssl_u加密。这也将添加openssl的填充。然后删除该填充(最后8个字节)。那么输出应该与mcrypt_Encrypt_Encrypt_Encryptê匹配。我不确定我是否遵循了。您可以将此作为您答案的一部分,并用代码示例说明您的意思吗?谢谢。
$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";

$message_padded = $message;
if (strlen($message_padded) % 8) {
    $message_padded = str_pad($message_padded,
        strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key,
    $message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC", 
    $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));
4c6f72656d20697073756d => c6fed0af15d494e485af3597ad628cec
4c6f72656d20697073756d0000000000 => c6fed0af15d494e485af3597ad628cec