You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crypto++传递std::string格式IV解密出现PKCS#7块填充错误怎么解决

问题根因
  • 核心错误:解密时仅对IV做了Hex解码,拿到的encMessage仍然是Hex编码后的字符串,没有做解码就直接传入AES解密过滤器,导致输入的密文本身就是错误的,解密后的数据不符合PKCS#7填充规则,直接抛出校验错误。
  • 次要问题1:你使用的密钥字符串UltraSecretKeyPhrase长度不符合AES规范要求,AES密钥必须为16字节(AES-128)、24字节(AES-192)、32字节(AES-256),非标准长度会导致Crypto++内部自动截断,存在不可预期的行为。
  • 次要问题2:decc函数匹配不到::分隔符时返回NULL,与返回值类型std::string不匹配,会触发运行时异常。
修复代码

你只需要在解密环节给encMessage增加Hex解码步骤即可,以下是完整修正代码:

#include <crypto++/aes.h>
#include <crypto++/modes.h>
#include <crypto++/filters.h>
#include <crypto++/osrng.h>
#include <crypto++/hex.h>
#include <iostream>

using namespace std;
using namespace CryptoPP;

string encc(string plain) {
    AutoSeededRandomPool prng;

    SecByteBlock iv(AES::BLOCKSIZE);
    // 密钥调整为32字节适配AES-256,你也可以用哈希函数从任意长度口令派生固定长度密钥
    std::string sKey = "UltraSecretKeyPhrase1234567890";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    prng.GenerateBlock(iv, iv.size());
    std::string cipher, recovered;

    try
    {
        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, key.size(), iv);

        StringSource s(plain, true,
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) 
        ); 
    }
    catch (const Exception& e)
    {
        cerr << e.what() << endl;
        exit(1);
    }

    string ciphertxt, ivString;

    HexEncoder encoder;
    encoder.Attach(new StringSink(ivString));
    encoder.Put(iv, iv.size());
    encoder.MessageEnd();

    encoder.Attach(new StringSink(ciphertxt));
    encoder.Put((const byte*)&cipher[0], cipher.size());
    encoder.MessageEnd();

    string toSend = ivString + "::" + ciphertxt;
    return toSend;
}

string decc(string toDec) {
    std::string sKey = "UltraSecretKeyPhrase1234567890";
    SecByteBlock key((const unsigned char*)(sKey.data()), sKey.size());
    
    std::string recovered;
    string str1 = "::";

    size_t found = toDec.find(str1);
    if (found != string::npos) {

        std::string sIv = toDec.substr(0, found);
        std::string encMessage = toDec.substr(found + 2, toDec.length());
        
        // 解码IV
        string iv;
        HexDecoder decoder;
        decoder.Attach(new StringSink(iv));
        decoder.Put((byte*)sIv.data(), sIv.size());
        decoder.MessageEnd();

        // 新增:对Hex编码的密文做解码
        string decodedCipher;
        HexDecoder cipherDecoder;
        cipherDecoder.Attach(new StringSink(decodedCipher));
        cipherDecoder.Put((byte*)encMessage.data(), encMessage.size());
        cipherDecoder.MessageEnd();

        try
        {
            CBC_Mode< AES >::Decryption d;
            d.SetKeyWithIV(key.data(), key.size(), (byte *)iv.data(), AES::BLOCKSIZE);
            // 传入解码后的二进制密文而非原始Hex字符串
            StringSource s(decodedCipher, true,
                new StreamTransformationFilter(d,
                    new StringSink(recovered)
                )
            );
            return recovered;
        }
        catch (const Exception& e)
        {
            std::cerr << e.what() << std::endl;
            exit(1);
        }
    }
    else return "";
}

int main(){
    string hh = encc("this is encoded");
    cout << hh << endl;
    string gg = decc(hh);
    cout << gg << endl;
    return 0;
}

内容的提问来源于stack exchange,提问作者Comet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:24:03