如何在使用 CryptoPP 解密流后执行 unpadding
Posted
技术标签:
【中文标题】如何在使用 CryptoPP 解密流后执行 unpadding【英文标题】:How to perform unpadding after decryption of stream using CryptoPP 【发布时间】:2013-10-07 11:05:36 【问题描述】:我有要解密的流。我将它分成块并将每个块传递给下面的方法。我需要解密的数据由 16 字节块加密,如果最后一个块小于 16,则所有其余字节都由填充填充。然后在解密的那一刻,我将我的最后一个块结果作为包含这些额外填充字节的值。考虑到可以使用不同的填充,我如何确定原始数据的长度并仅返回它或确定填充字节并删除它们?
void SymmetricAlgorithm::Decrypt(byte* buffer, size_t dataBytesSize)
MeterFilter meter(new ArraySink(buffer, dataBytesSize));
CBC_Mode<CryptoPP::Rijndael>::Decryption dec(&Key.front(), Key.size(), &IV.front());
StreamTransformationFilter* filter = new StreamTransformationFilter(dec, new Redirector(meter), PKCS_PADDING);
ArraySource(buffer, dataBytesSize, true, filter);
dec.Resynchronize(&IV.front());
现在我正在尝试使用 PKCS_PADDING 和 Rijndael,但通常我可能需要使用任何算法和任何填充。
【问题讨论】:
【参考方案1】:我把它分成块,每个块传递给下面的方法
在这种情况下,您可以考虑直接调用ProcessBlock
:
CBC_Mode<Rijndael>::Decryption dec(...);
// Assume 'b' is a 16-byte block
dec.ProcessBlock(b);
该块已就地处理,因此具有破坏性。您还将负责处理最后一个块,包括删除填充。
通过阻止和删除填充,您正在完成StreamTransformationFilter
(和朋友)的工作。
【讨论】:
对不起,但我看不到 ProcessBlock() 方法,只有 ProcessLastBlock() 如果它调用我的 16 字节块,它只有 1 个有效符号和 15 个由填充填充,我得到与使用我的代码形成初始问题相同的结果。至于StreamTransformationFilter,你是对的,我实际上在这个类中找到了需要的方法,它叫做GetTotalBytes,我在这里将它作为单独的答案发布。无论如何感谢您的帮助。【参考方案2】:碰巧,我在这个question 的示例中发现了我偶尔需要的东西。 感谢您的帮助,Gabriel L.,但我不想让我的方法根本不使用填充。抱歉解释不清楚,我想从解密数据中提取纯数据,其中包括填充符号。此代码中的粗体行显示了如何找出纯数据字节数。
void SymmetricAlgorithm::Decrypt(byte* buffer, size_t dataBytesSize)
MeterFilter meter(new ArraySink(buffer, dataBytesSize));
CBC_Mode<CryptoPP::Rijndael>::Decryption dec(&Key.front(), Key.size(), &IV.front());
StreamTransformationFilter* filter = new StreamTransformationFilter(dec, new Redirector(meter), PKCS_PADDING);
ArraySource(buffer, dataBytesSize, true, filter);
int t = meter.GetTotalBytes(); //plain data bytes count
dec.Resynchronize(&IV.front());
【讨论】:
以上是关于如何在使用 CryptoPP 解密流后执行 unpadding的主要内容,如果未能解决你的问题,请参考以下文章