繁体   English   中英

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

[英]AES-128-CBC encryption with OpenSSL/C++ and PHP/Mcrypt: the 1st block is decrypted only

我编写了必须与基于PHP的Web服务交换加密数据的程序。 我在CBC模式下将C ++与OpenSSL一起使用AES-128加密数据。 我将base64编码的数据(IV和密文)发送到HTTP服务器,PHP必须使用Mcrypt解密数据。 但是,只有第一个块被成功解密,其他块变成垃圾。 我一点都不明白:我们如何仅在CBC模式下才能解密第一个块? 如果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的错误还是有任何方法可以使用OpenSSL AES-128-CBC加密数据并使用PHP mcrypt对其解密?

好吧,错误是在C ++方面。 我加密的数据是部分传输的,因此我不得不多次调用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非常出色,我看到的问题是程序错误而不是mcrypt。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM