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

使用OpenSSL/C++和PHP/mcrypt进行AES-128-CBC加密:仅解密第一个块

尹昂雄
2023-03-14

我编写的程序必须与基于PHP的web服务交换加密数据。我使用C++和OpenSSL在CBC模式下用AES-128加密数据。我将Base64编码的数据(IV和密文)发送到HTTP服务器,PHP必须用mcrypt解密数据。然而,只有第1块被成功解密,其他块都成为垃圾。我完全不明白:我们怎么只能在CBC模式下解密第1块?如果IV、密钥大小/块大小/轮数等密钥或算法设置错误,则不能正确接收到解密后的第一块;如果解密参数是可以的,怎么可能其他块没有被解密呢?当我解密PHP无法用OpenSSL/C++解密的相同密文时,解密成功。对于PHP也是如此:我可以在CBC模式下加密和解密数据。但由于任何原因,OpenSSL EVP_aes_128_cbc和mcrypt'rijndael-128'不兼容。我的解密代码如下:

$chipher = mcrypt_module_open('rijndael-128', '', 'cbc', '');  
mcrypt_generic_init($chipher, $key, $iv);
$decrypted_data = mdecrypt_generic($chipher, $encrypted_data);

是mcrypt的bug还是有什么方法可以用OpenSSL AES-128-CBC加密数据,用PHP mcrypt解密?

共有1个答案

鲜于温书
2023-03-14

错误出在C++方面。我html" target="_blank">加密的数据是按零件来的,所以我不得不多次调用EVP_CipherUpdate;因为在重复调用EVP_CipherUpdate时,会复制到输出缓冲区的数据太多,而且只有最后一个块,所以我不得不重复调用EVP_CipherInit_ex来清除OpenSSL上下文中的内部缓冲区。当我调用EVP_CipherInit_ex时,它重置IV,所以在某个点之后解密变得不可能。解决方案是在每次EVP_CipherUpdate调用后,将上一个版本的IV(context.IV指向上一个IV,context.oiv指向原始版本)保存在缓冲区中,并将其传递给EVP_CipherInit_ex,以允许OpenSSL按部分加密数据。当我这样做时,mcrypt能够解密整个数据,甚至删除填充。所以,mcrypt是优秀的,我看到的问题是我的程序bug而不是mcrypt。

 类似资料:
  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB

  • 我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/

  • 我只需要通过代码加密AES CBC 128位模式的字符串。我使用openssl库完成了这项工作,但无法获得正确的输出。 到目前为止,我已经完成了。 我的十六进制输出是:B0 15 751B50 80 D4 FF 81 68 146BB71B95 99 37 38 但正确的输出是:< code > 73 5C 04 F9 57 18 43 7C EE 68 27 59 2B 41 A8 DA (通过

  • 我是密码学的新手。我的要求是对使用openssl加密/解密的文本进行解密/加密。我们在Openssl中使用的算法是aes-256-cbc。因此,我尝试在我的应用程序中实现相同的功能。到目前为止,在谷歌搜索了很多次之后,我所能做的就是。。 我的openssl命令是 我的密钥长度是32位IV是16位 Thnx...

  • 我正在使用以下函数通过Qt中的OpenSSL库加密我的数据: “源”在“123456789012345678901234567890123456789012ABC”中。 “密码”为“1HA!DH==SJAH48S8AK!?SKIITFI120XX”。 所以...如果我正确的话,那么EVP_BytesToKey()应该从密码中生成一个密钥,并提供数据以在后面解密字符串。 对base64编码的密钥是:

  • 最近,我终于(在stackoverflow的用户@WhozCraig的帮助下)开始在CBC模式下使用AES。现在,我想用AES IGE做同样的事情。我看了并尝试构建自己的测试。但是,我再次遇到了输入和输出大小合适的问题。其他一切都很好,因为我从以前的代码中复制了它:AES(aes-cbc-128、aes-cbc-192、aes-cbc-256)使用openssl C进行加密/解密。 现在,当我传递