MIP SDK 1.14无法解密Purview新生成CBC加密AIP文件求助
解密Purview新生成CBC加密AIP文件的问题解决
核心问题分析
Purview新生成的AIP文件采用了CBC模式的AES加密,当前一次性传入整个加密缓冲区并标记isFinal=true的实现,不符合CBC模式的分块解密逻辑——CBC需要按固定16字节的块大小逐步处理,最后一块的PKCS7填充验证需要单独处理,全量传入会导致加密引擎无法正确解析最终块,从而抛出AESCryptoWriter: Failed to transform final block错误。
必要的代码调整
无需额外配置SDK,但必须修改DecryptBuffer的调用逻辑,改为分块处理加密数据:
- 定义AES块大小常量:
const int64_t AES_BLOCK_SIZE = 16; - 分批次处理加密数据,完整块与最后剩余块分开处理:
int64_t totalDecrypted = 0; int64_t inputOffset = 0; const auto& encryptedData = content.encryptedData; const int64_t inputSize = static_cast<int64_t>(encryptedData.size()); // 处理所有完整的16字节块 while (inputOffset + AES_BLOCK_SIZE <= inputSize) { int64_t decrypted = handler->DecryptBuffer( inputOffset, &encryptedData[inputOffset], AES_BLOCK_SIZE, &outputBuffer[totalDecrypted], static_cast<int64_t>(outputBuffer.size()) - totalDecrypted, false); // 非最终块,isFinal设为false totalDecrypted += decrypted; inputOffset += AES_BLOCK_SIZE; } // 处理剩余的最后一块(可能不足16字节) if (inputOffset < inputSize) { int64_t remainingSize = inputSize - inputOffset; int64_t decrypted = handler->DecryptBuffer( inputOffset, &encryptedData[inputOffset], remainingSize, &outputBuffer[totalDecrypted], static_cast<int64_t>(outputBuffer.size()) - totalDecrypted, true); // 最后一块,isFinal设为true totalDecrypted += decrypted; } outputBuffer.resize(static_cast<size_t>(totalDecrypted));
关键注意事项
- 初始化
outputBuffer时,大小建议直接设为加密数据的长度,确保能容纳解密后的内容。 - 只有最后一次调用
DecryptBuffer时才将isFinal设为true,前面的完整块调用必须设为false,这是CBC模式解密的硬性要求。 - MIP SDK 1.13+默认支持CBC加密,但依赖正确的分块调用逻辑来处理填充验证,全量传入会破坏这一流程。
内容的提问来源于stack exchange,提问作者Ravish Mahajan
相关产品推荐
相关产品推荐

