如何在使用 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的主要内容,如果未能解决你的问题,请参考以下文章

使用 AES 加密/解密

CryptoPP:如何使用 SocketSource 和 SocketSink

如何使用 mingw 编译 cryptopp 5.6.2

数据上的节点 js 仅在写入流后执行

Crypto ++在加密/解密期间显式破坏?

CryptoPP 使用方法