Php 如何使用DES-CBC方法使用openSLL进行加密

Php 如何使用DES-CBC方法使用openSLL进行加密,php,encryption,openssl,mcrypt,des,Php,Encryption,Openssl,Mcrypt,Des,实际上我正在使用Mcrypt,但我正在转向OpenSSL,我需要能够以与Mcrypt完全相同的方式使用它 这就是我加密的方式 mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0"); 对于解密,我已经在OpenSSL中实现了,两者的工作方式完全相同 //Using Mcrypt mcrypt_decrypt(MCRYPT_DES, $key, $enc, MCRYPT_MODE

实际上我正在使用Mcrypt,但我正在转向OpenSSL,我需要能够以与Mcrypt完全相同的方式使用它

这就是我加密的方式

mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");
对于解密,我已经在OpenSSL中实现了,两者的工作方式完全相同

//Using Mcrypt
mcrypt_decrypt(MCRYPT_DES, $key, $enc, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");

//Using Openssl
openssl_decrypt($enc, 'des-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); 
对于使用OpenSSL的加密,这是我的测试代码

$key = "123456SO";
$text = "name=louis&cp=75013";

$encMcrypt = mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");
$encOpenssl = openssl_encrypt($text, "des-cbc", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0");

echo "Mcrypt : " . urlencode(base64_encode($encMcrypt));
echo " OpenSsl : " . urlencode(base64_encode($encOpenssl));
这是输出:

Mcrypt : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD OpenSsl :
这是最简单的方法,但我找不到DES方法

我知道Openssl声明DES很弱,但我仍然需要在我的情况下使用它

如何使用OpenSSL在DES-CBC中加密,并使其与Mcrypt函数的行为相同

编辑:

如果我删除了
OPENSSL\u ZERO\u PADDING
选项,结果几乎是预期的结果

代码:

输出:

Mcrypt  : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
OpenSsl : f0tF0ERITdKiI2SxrttYANpJ%2BZaEiIFr
字符串的第一部分是正确的,但最后它与Mcrypt加密字符串的输出不同。

多亏了我,我才使它工作起来

我添加了
OPENSSL\u ZERO\u PADDING
选项来禁用PKCS7填充,然后我创建了一个函数来手动填充字符串
0x00

function zero_padding($text)
{
    if (strlen($text) % 8)
        $text = str_pad($text,strlen($text) + 8 - strlen($text) % 8, "\0");
    
    return $text;
}

$key = "123456SO";
$text = "name=louis&cp=75013";

$encMcrypt = mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");
$encOpenssl = openssl_encrypt(zero_padding($text), "des-cbc", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0");

$encMcrypt = urlencode(base64_encode($encMcrypt));
$encOpenssl = urlencode(base64_encode($encOpenssl));

echo "Mcrypt :" . $encMcrypt;
echo "OpenSsl:" . $encOpenssl;
输出:

Mcrypt : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
OpenSsl: f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD

mcyrpt使用零填充,openssl PKCS7填充。对于openssl,必须显式实现零填充。必须使用
OPENSSL\u ZERO\u padding
禁用第一个PKCS7填充(注意,名称选择错误:此标志仅禁用PKCS7填充,不启用零填充)。接下来,实现零填充,即如果明文长度不是块大小的整数倍(DES为8字节),则用
0x00
值填充明文,即对于发布的明文:
“name=louis&cp=75013\0\0\0\0”
,这给出了mcrypt密文。关于解密,应该补充的是,mcrypt并没有明确删除零填充。因此,它在功能上与使用OPENSSL解密时仅设置
OPENSSL\u ZERO\u PADDING
完全相同。@Topaco我不知道“OPENSSL\u ZERO\u PADDING”实际上在加密中没有启用零填充,谢谢。我将尝试自己实现零填充
Mcrypt : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
OpenSsl: f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD