【问题标题】:How to encrypt with openSLL using the DES-CBC method如何使用 DES-CBC 方法使用 openSSL 进行加密
【发布时间】:2020-12-04 05:15:01
【问题描述】:

实际上我正在使用 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 :

这是official list of method,但我找不到 DES 方法。

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

如何在 DES-CBC 中使用 OpenSSL 进行加密并使其行为方式与 Mcrypt 函数相同?

编辑:

如果我删除了OPENSSL_ZERO_PADDING 选项,结果几乎是预期的

代码:

openssl_encrypt($text, "des-cbc", $key, OPENSSL_RAW_DATA , "\0\0\0\0\0\0\0\0");

输出:

Mcrypt  : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
OpenSsl : f0tF0ERITdKiI2SxrttYANpJ%2BZaEiIFr

字符串的第一部分是正确的,但最后它与 Mcrypt 加密字符串的输出不同。

【问题讨论】:

  • mcyrpt 使用零填充,openssl PKCS7 填充。对于 openssl,必须显式实现零填充。首先必须使用OPENSSL_ZERO_PADDING 禁用 PKCS7 填充(注意,名称选择不当:此标志仅禁用 PKCS7 填充,它不启用零填充)。接下来,实现零填充,即用0x00 值填充明文,如果它的长度不是块大小的整数倍(DES 为8 字节),即对于发布的明文:"name=louis&cp=75013\0\0\0\0\0",它给出了 mcrypt 密文。
  • 关于解密,应该补充一点 mcrypt 不会显式删除零填充。因此,在openssl的解密中只设置OPENSSL_ZERO_PADDING在功能上是相同的。
  • @Topaco 我不知道“OPENSSL_ZERO_PADDING”实际上没有在加密中启用零填充,谢谢。我会尝试自己实现零填充

标签: php encryption openssl mcrypt des


【解决方案1】:

感谢@Topaco 我成功了

我添加了 OPENSSL_ZERO_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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多