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

如何在内存中解密文件?CryptoPP内存解密失败问题

内存中AES-CTR解密失败问题

背景代码

文件加密实现

#include <cryptopp/files.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/base64.h>
#include <cryptopp/hex.h>
#include <Windows.h>
#include <iostream>
#include <fstream>


void FileEncrypt(byte key[], byte iv[]
               , const std::string& file, const std::string& dest)
{
    CTR_Mode< AES >::Encryption cipher;
    cipher.SetKeyWithIV(key, strlen((char*)key), iv, strlen((char*)iv));

    std::ifstream in{file, std::ios::binary};
    std::ofstream out{dest, std::ios::binary};

    CryptoPP::FileSource{in, true,
            new CryptoPP::StreamTransformationFilter{
            cipher, new CryptoPP::FileSink{out}}};
} 

INT main(INT argc, PCHAR* argv)
{
    std::string file = "...";
    std::string dest = "...";

    unsigned char* key[] = "p3s6v9y$B&E)H@Mc";
    unsigned char* iv[] = "VkXp2s5v8y/B?E(H";

    FileEncrypt(key, iv, file, dest);
    FileDecrypt(key, iv, file, dest);
}

磁盘文件解密实现

void FileDecrypt(byte key[], byte iv[]
               , const std::string& file, const std::string& dest)
{
     CTR_Mode< AES >::Decryption cipher;
     cipher.SetKeyWithIV(key, strlen((char*)key), iv, strlen((char*)iv));
     
     std::ifstream in{file, std::ios::binary};
     std::ofstream out{dest, std::ios::binary};
 
     CryptoPP::FileSource{in, true,
                          new StreamTransformationFilter{
                              cipher, new CryptoPP::FileSink{out}}};
}

问题描述

上述磁盘解密会将结果写入磁盘,现在需要在内存中直接解密已下载到内存的加密文件。尝试了以下代码,但dec变量未得到正确解密结果:

std::string data;
FileDownload(data, "https://github.com/..."));

//...

std::string dec;

try {
    CTR_Mode< AES >::Decryption d;
    d.SetKeyWithIV(key, strlen((char*)key), iv, strlen((char*)iv));

    StringSource s(data, true,
        new StreamTransformationFilter(d,
        new StringSink(dec)));
}
catch (const CryptoPP::Exception& e)
{
    std::cerr << e.what() << std::endl;
}

解决方案及问题分析

  • 密钥/IV的类型与长度问题
    原代码中unsigned char* key[] = "p3s6v9y$B&E)H@Mc";是错误写法,这里声明的是指针数组而非单个指针,正确写法应为const unsigned char* key = (const unsigned char*)"p3s6v9y$B&E)H@Mc";。

    另外要明确:AES密钥长度必须是128/192/256位(对应16/24/32字节),你的密钥正好是16字节(128位),符合要求;CTR模式下IV通常和AES块大小一致(16字节),你的IV长度也合规,但必须保证加密、解密使用完全相同的密钥和IV。

  • 下载数据的完整性问题
    确保FileDownload函数以二进制模式下载数据。如果默认用文本模式,会自动转换部分二进制字节(如0x0A、0x0D),导致加密数据损坏,解密必然失败。

  • 修正后的内存解密代码

    #include <cryptopp/modes.h>
    #include <cryptopp/filters.h>
    #include <cryptopp/strings.h>
    #include <string>
    #include <iostream>
    
    // 正确定义密钥和IV
    const unsigned char* key = (const unsigned char*)"p3s6v9y$B&E)H@Mc";
    const unsigned char* iv = (const unsigned char*)"VkXp2s5v8y/B?E(H";
    
    int main() {
        std::string encrypted_data;
        // 确保FileDownload以二进制方式获取数据
        FileDownload(encrypted_data, "https://github.com/...");
    
        std::string decrypted_data;
        try {
            CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption decryptor;
            // 明确指定密钥和IV长度,避免strlen处理二进制数据出错
            decryptor.SetKeyWithIV(key, 16, iv, 16);
    
            CryptoPP::StringSource(
                encrypted_data, 
                true, 
                new CryptoPP::StreamTransformationFilter(
                    decryptor, 
                    new CryptoPP::StringSink(decrypted_data)
                )
            );
    
            // 验证解密结果,比如输出数据长度或对比本地解密内容
            std::cout << "Decryption successful, data length: " << decrypted_data.size() << std::endl;
        } catch (const CryptoPP::Exception& e) {
            std::cerr << "Decryption error: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  • 额外验证步骤

    • 将加密文件本地解密,把本地解密后的二进制内容和内存解密得到的decrypted_data做字节对比,确认一致性;
    • 如果下载的数据是Base64编码的加密内容,需要添加Base64Decoder过滤器处理:
      CryptoPP::StringSource(
          encrypted_data, 
          true, 
          new CryptoPP::Base64Decoder(
              new CryptoPP::StreamTransformationFilter(
                  decryptor, 
                  new CryptoPP::StringSink(decrypted_data)
              )
          )
      );
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:40:34