首页 文章

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

提问于
浏览
1

我编写的程序必须与基于PHP的Web服务交换加密数据 . 我使用C和OpenSSL在CBC模式下使用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解密?

1 回答

  • 0

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

相关问题