MCrypt rijndael-128到OpenSSL aes-128-ecb转换

时间:2017-07-20 15:00:14

标签: php encryption cryptography mcrypt php-openssl

由于Mcrypt已被弃用,我想在我的代码中使用OpenSSL,因为我们已经在服务器中使用 php 7.0.17 ,并且在升级它时没有说明。

某些第三方API(可能在 PHP 5.x 上托管并使用 mcrypt )正在使用加密数据。他们提供了用于加密/解密字符串的方法。

他们是

v7IXp5vVaFVXXlt/MN8BVw==

如果加密变为openssl_encrypt

,则使用这些方法字符串aes-128-ecb

我们希望在我们这边使用public function sslEncrypt128($str) { $secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c'; return base64_encode(openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA)); } ,这样如果我们用OpenSSL加密相同的字符串,它必须给出与Mcrypt相同的结果。我已经研究过使用 rijndael-128 模式 ecb 的mcrypt应该与OpenSSL SxJ3+EdaeItZx3/EwGTUbw==兼容。

在过去的几个小时里,我一直在尝试使用自己的方法来加密使用OpenSSL提供相同结果的字符串。到目前为止,我已经来到这个

{{1}}

但它产生与上述输入相同的不同字符串{{1}}。我不知道这是标志问题还是填充,欢迎提出任何指示。

我已在此处添加了代码,以便在线测试https://3v4l.org/v2J2N

提前致谢。

3 个答案:

答案 0 :(得分:5)

在您的具体示例中,我发现通过将aes-128-ecb更改为aes-256-ecb,它会产生与旧版mcrypt_encrypt相同的输出。

答案 1 :(得分:3)

这对我有用:

<?php

$str = 'Content';
if (strlen($str) % 16) {
    $str = str_pad($str, strlen($str) + 16 - strlen($str) % 16, "\0");
}

$key = 'KEY';
if (strlen($key) % 16) {
    $key = str_pad($key, strlen($key) + 16 - strlen($key) % 16, "\0");
}

$res1 = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
echo strToHex($res1) . ' | mcrypt_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res1, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';

echo "<hr>";

$res2 = openssl_encrypt($str, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
echo strToHex($res2) . ' | openssl_encrypt';

echo "<hr>";
echo strToHex(openssl_decrypt($res2, "aes-128-ecb", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)) . ' | openssl_decrypt';


function strToHex($string) {
    $hex = '';
    for ($i = 0; $i < strlen($string); $i++) {
        $ord     = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex     .= substr('0' . $hexCode, -2);
    }

    return strToUpper($hex);
}

答案 2 :(得分:2)

最有可能的是,密钥被用作十六进制(它已经是十六进制格式)而不是要转换为十六进制的字符串。

mcrypt:

mcrypt不支持标准PKCS#7(néePKCS#5)填充,只支持非标准空填充,但填充是在mcrypt 之前显式添加的。

加密v7IXp5vVaFVXXlt/MN8BVw==是基于PKCS#7填充的正确加密。 ECB模式和密钥作为字符串。

请参阅:mcrypt - AES CALCULATOR

以十六进制表示,请注意数据填充清晰可见:
key: 6130613765373939376236643566636435356634623563333236313162383763
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: BFB217A79BD56855575E5B7F30DF0157

在Base64中:
encrypted: v7IXp5vVaFVXXlt/MN8BVw==

OpenSSL的:

注意密钥是256位,但带有“aes-128-ecb”的OpenSSL调用似乎意味着128但是密钥。因此密钥不匹配。

请参阅:OpenSSL - AES CALCULATOR

以十六进制表示,请注意数据填充清晰可见:
key: 61306137653739393762366435666364
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
encrypted: 4B1277F8475A788B59C77FC4C064D46F

在Base64中:
encrypted: SxJ3+EdaeItZx3/EwGTUbw==