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

C++客户端加密文件传Python服务器解密后丢失前16字节的解决方法

问题:AES加密传输后丢失前16字节的解决方法

用C++ Crypto++编写的客户端加密文件后,发送给Python Crypto.Cipher实现的服务器,解密后原文件前16个字符总是丢失。例如原文件内容为AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC,解密后变为BBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC。

相关代码

C++客户端加密函数

std::string encryptFile(const std::string& filename, const CryptoPP::SecByteBlock& key) {
// Step 1: Read the file to be encrypted
std::ifstream input_file(filename, std::ios::binary);
std::string plaintext((std::istreambuf_iterator<char>(input_file)),
    std::istreambuf_iterator<char>());

CryptoPP::SecByteBlock iv(CryptoPP::AES::BLOCKSIZE);

CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor(key, key.size(), iv);

// Step 2: Encrypt the file
std::string ciphertext;
CryptoPP::StringSource s(plaintext, true,
    new CryptoPP::StreamTransformationFilter(encryptor,
        new CryptoPP::StringSink(ciphertext)));

return ciphertext;
}

Python服务器解密函数

def decrypt_file(self, encrypted_data, aes_key, file_path):
        key = base64.b64decode(aes_key)
        iv = encrypted_data[:AES.block_size]
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        plaintext = cipher.decrypt(encrypted_data[AES.block_size:])
        # Remove PKCS#7 padding
        padding_len = plaintext[-1]
        plaintext = plaintext[:-padding_len]

        with open(file_path, "wb") as f:
            f.write(plaintext)

解决方法

问题核心是客户端未将IV(初始化向量)写入加密后的密文头部,但服务器默认从加密数据的前16字节读取IV,相当于把密文的前16字节误当成了IV,剩下的密文解密自然缺失了前16字节内容。同时原客户端代码的IV是未初始化的垃圾值,存在安全隐患,必须修正。

1. 修改C++客户端加密逻辑

生成随机合法的IV,并将其拼接在密文的最前方再发送:

std::string encryptFile(const std::string& filename, const CryptoPP::SecByteBlock& key) {
    // 读取文件内容
    std::ifstream input_file(filename, std::ios::binary);
    std::string plaintext((std::istreambuf_iterator<char>(input_file)),
        std::istreambuf_iterator<char>());

    // 生成随机IV(AES-CBC要求IV必须随机且唯一,禁止使用未初始化值)
    CryptoPP::SecByteBlock iv(CryptoPP::AES::BLOCKSIZE);
    CryptoPP::AutoSeededRandomPool prng;
    prng.GenerateBlock(iv, iv.size());

    CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor(key, key.size(), iv);

    std::string ciphertext;
    // 先将IV写入密文开头
    ciphertext.assign(reinterpret_cast<const char*>(iv.data()), iv.size());
    
    // 执行加密并追加到密文后
    CryptoPP::StringSource s(plaintext, true,
        new CryptoPP::StreamTransformationFilter(encryptor,
            new CryptoPP::StringSink(ciphertext)));

    return ciphertext;
}

2. 服务器端无需修改

当前Python服务器的逻辑是正确的:从加密数据头部读取IV,用剩余内容解密,只要客户端补上IV,就能正常解密出完整的原文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:33:34