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

Python AES加密文件后,Windows平台C++解密问题求助

问题:Python AES加密文件后,Windows C++端解密遇到编译与运行问题

背景

我用Python实现了AES加密文件的代码,通过HTTP将加密文件发送到Windows平台的C客户端,希望在C端完成解密,但一直没找到合适的库或可用代码。

Python加密代码

def derive_key_and_iv(password, salt, key_length, iv_length):
    d = d_i = b''
    while len(d) < key_length + iv_length:
        d_i = md5(d_i + str.encode(password) + salt).digest()
        d += d_i

    return d[:key_length], d[key_length:key_length + iv_length]

def encrypt(in_file, out_file, password, key_length=32):
    bs = AES.block_size # 16 bytes
    salt = urandom(bs)
    key, iv = derive_key_and_iv(password, salt, key_length, bs)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    out_file.write(salt)
    finished = False
    while not finished:
        chunk = in_file.read(1024 * bs)
        if len(chunk) == 0 or len(chunk) % bs != 0: #final block
            padding_length = (bs - len(chunk) % bs) or bs
            chunk += str.encode(padding_length * chr(padding_length))
            finished = True
        out_file.write(cipher.encrypt(chunk))

password = 'ABCDE' # some password

with open("some_file.bin", "rb") as in_file, open("enc_some_file.enc", "wb") as out_file:
    encrypt(in_file, out_file, password)

更新:尝试用WinCrypt实现解密的C++代码

我在Windows上使用VS Code搭配MSYS64 g编译器编译,用libcurlpp和libcurl处理客户端-服务端交互,写出了如下C代码:

#include <string>
#include <sstream>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <wincrypt.h>
#include <windows.h>

#define AES_KEY_SIZE 32
#define IN_CHUNK_SIZE (AES_KEY_SIZE * 10) // a buffer must be a multiple of the key size
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2) // an output buffer (for encryption) must be twice as big

using namespace std;

string host = ""; // some host

int main(void)
{
    curlpp::Easy req;
    req.setOpt(new curlpp::options::Url(host));
    ofstream myfile;
    myfile.open("enc_calc.enc", ios::out | ios::binary);
    myfile << req;
    myfile.close();
    getch();
    wchar_t *in_file = (wchar_t *)"enc_calc.enc";
    wchar_t *out_file = (wchar_t *)"calc.dll";

    wchar_t default_key[] = L"ABCDE";
    wchar_t *key_str = default_key;
    const size_t len = lstrlenW(key_str);
    const size_t key_size = len * sizeof(key_str[0]);
    const wchar_t *filename1 = (const wchar_t *)"enc_calc.enc";
    const wchar_t *filename2 = (const wchar_t *)"calc.dll";

    HANDLE hInpFile = CreateFileW(filename1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (hInpFile == INVALID_HANDLE_VALUE) {
        printf("Cannot open input file!\n");
        system("pause");
        return (-1);
    }
    HANDLE hOutFile = CreateFileW(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hOutFile == INVALID_HANDLE_VALUE) {
        printf("Cannot open output file!\n");
        system("pause");
        return (-1);
    }

    DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
    HCRYPTPROV hProv;

    if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %x\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        system("pause");
        return dwStatus;
    }
    HCRYPTHASH hHash;
    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        dwStatus = GetLastError();
        printf("CryptCreateHash failed: %x\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        system("pause");
        return dwStatus;
    }

    if (!CryptHashData(hHash, (BYTE*)key_str, key_size, 0)) {
        DWORD err = GetLastError();
        printf("CryptHashData Failed : %#x\n", err);
        system("pause");
        return (-1);
    }
    printf("[+] CryptHashData Success\n");

    HCRYPTKEY hKey;
    if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
        dwStatus = GetLastError();
        printf("CryptDeriveKey failed: %x\n", dwStatus);
        CryptReleaseContext(hProv, 0);
        system("pause");
        return dwStatus;
    }
    printf("[+] CryptDeriveKey Success\n");

    const size_t chunk_size = IN_CHUNK_SIZE;
    BYTE *chunk = new BYTE[chunk_size];
    DWORD out_len = 0;

    BOOL isFinal = FALSE;
    DWORD readTotalSize = 0;

    DWORD inputSize = GetFileSize(hInpFile, NULL);

    while (bResult = ReadFile(hInpFile, chunk, IN_CHUNK_SIZE, &out_len, NULL)) {
        if (0 == out_len) {
            break;
        }
        readTotalSize += out_len;
        if (readTotalSize >= inputSize) {
            isFinal = TRUE;
            printf("Final chunk set, len: %d = %x\n", out_len, out_len);
        }

        if (!CryptDecrypt(hKey, NULL, isFinal, 0, chunk, &out_len)) {
            printf("[-] CryptDecrypt failed: %x\n", GetLastError());
            break;
        }
    
        DWORD written = 0;
        if (!WriteFile(hOutFile, chunk, out_len, &written, NULL)) {
            printf("writing failed!\n");
            break;
        }
        memset(chunk, 0, chunk_size);
    }

    delete[]chunk; chunk = NULL;

    CryptDestroyHash(hHash);
    CryptDestroyKey(hKey);
    CryptReleaseContext(hProv, 0);

    CloseHandle(hInpFile);
    CloseHandle(hOutFile);
    printf("Finished. Processed %#x bytes.\n", readTotalSize);
    return 0;
}

当前遇到的问题

  • 编译时出现windows.h库相关错误,例如“ULONG does not name a type”
  • 运行时提示“Cannot Open input file”,但文件已经下载到当前目录

内容的提问来源于stack exchange,提问作者C. Cristi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:55:27