当前位置: 首页 > 知识库问答 >
问题:

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

颜乐
2023-03-14

由于Mcrypt已被弃用,我想在我的代码中使用OpenSSL,因为我们已经在服务器中使用了php7.0.17,并且不知道他们何时升级它。

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

他们在这里

$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c' ;

public function encrypt128($str)
    {
        $block = mcrypt_get_block_size("rijndael_128", "ecb");
        $pad   = $block - (strlen($str) % $block);
        $str .= str_repeat(chr($pad), $pad);

        return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB));
    }

public function decrypt128($str)
    {
        $str = base64_decode($str);
        $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB);

        $len = strlen($str);
        $pad = ord($str[$len - 1]);

        return substr($str, 0, strlen($str) - $pad);
    }

使用这些方法string<code>small1</code>如果加密,则变为<code>v7IXp5vVaFVXlt/MN8BVw==</code>

我们希望在我们的身边使用openssl_encrypt,这样如果我们用OpenSSL加密相同的字符串,它必须给出与Mcrypt相同的结果。我已经研究过,使用里恩代尔-128模式的电子邮箱应该与OpenSSL aes-128-欧洲央行兼容。

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

public function sslEncrypt128($str)
{
    $secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c';
    return base64_encode(openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA));
}

但它会产生不同的字符串SxJ3 EdaeItZx3/EwGTUbw==,与上面的输入相同。我不知道这是标志的问题还是填充的问题,任何指针都会受到欢迎。

我在这里添加了代码来测试在线 https://3v4l.org/v2J2N

先谢谢你。

共有3个答案

王炜
2023-03-14

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

加密:

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

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

请参阅:mcrypt - AES计算器。

在十六进制中,请注意数据填充清晰可见:
密钥:6130613765373939376236643566636435356634623563333236313162383763
数据:736D616C6C310A0A0A0A0A0A0A0A0A 加密
:BFB217A79BD56855575E5B7F30DF0157

在Base64中:
加密:v7IXp5vVaFVXXlt/MN8BVw==

OpenSSL:

注意,密钥是256位的,但是带有“aes-128-ecb”的OpenSSL调用似乎暗示了128位的密钥。所以钥匙不匹配。

请参阅:OpenSSL - AES计算器

在十六进制中,注意数据填充是清晰可见的:
key:61306137653739393762366435666364
data: 736D616C6C310A0A0A0A0A0A0A0A0A0A
加密:4B1277F8475A788B59C77FC4C064D46F

在Base64中:< br > < code > encrypted:SxJ3 edaeitzx 3/EwGTUbw = =

长孙弘盛
2023-03-14

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

东郭勇
2023-03-14

以下是对我有用的方法:

<?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);
}
 类似资料:
  • 问题内容: 由于不建议使用Mcrypt,因此我想在代码中使用OpenSSL,因为我们已经在服务器中使用 php 7.0.17 ,并且不知道何时升级。 一些第三方API(可能在 PHP 5.x 上托管并使用 mcrypt )正在获取加密数据。他们提供了用于加密/解密字符串的方法。 他们在这 如果已加密,则使用这些方法字符串 我们想在我们这边使用,如果我们使用OpenSSL加密相同的字符串,则它必须提

  • 我用Delphi加密“sifrelenecek”字符串,使用AES 128 ECB,使用密钥为“KRPTTT101103”,它给了我“FBE4A4405D6C1B54503D9B213E41AE56”,我正在检查http://aes.online-domain-tools.com/,它是正确的。我试图使用此功能创建相同的PHP加密; 但是php给我的结果是“wL2yf 72thixicjw0duQ

  • 我不知道我做错了什么,在这里试图用给定的密钥解密一串十六进制值,使用ruby的OpenSSL密码AES-128-CTR。 我正在使用gem hex_字符串将我的十六进制转换为字节 我知道我遗漏了一些小东西,因为我有类似的代码实现AES-128-CBC。我是否需要一个计数器,为密文中128字节的每一块递增IV?

  • 我用java编写了这段代码,以便解密密文。我有钥匙。对我来说,一切都是正确的,但我有我要解释的问题。 这是我的代码: 我收到以下错误: 出了什么问题?我知道这个问题在某种程度上与衬垫有关,但我不知道确切的解决方案。我只有一个密文IV和密钥。

  • Ruby代码是 然后 现在PHP代码是 然后我得到 密文和ruby的不一样。现在我尝试用PHP制作的密文解密ruby。 Ruby 'AES-128-CBC '和PHP 'rijndael-128 '加密有区别吗?还有我怎么用ruby解密?

  • 关于AES有很多问题,但我有以下问题。我目前正在使用以下 AES 实现来加密数据 结果是32字节(256位)。所以我使用的是AES-256。这个实现对我来说太慢了。我如何切换到AES-128?我不需要任何填充或操作模式或密钥散列。 提前谢谢你。