I wrote this code to encrypt a file in python with AES and now I send this file over HTTP to a client in C++ using Windows OS. And I want to decrypt this file on the C++ client, but I haven't found any libraries/usefull code to help me with this manner. Here is the code for 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)
Update: I am updating this question regarding my try with WinCrypt. I am trying to compile from VS CODE using MSYS64 g++ compiler on Windows. Here is the code that I am trying to run. I also have some additional libraries to help me with the client-server part, such as libcurlpp and libcurl.
#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;
}
The errors I'm getting are regarding the windows.h library, such as:
"ULONG does not name a type" and other types in windows. and at runtime: "Cannot Open input file", not sure why, even tho the file is downloaded in the current folder and I'm trying to open it as such in the code.