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
相关产品推荐
相关产品推荐

