I need to generate (in C/C++) a secure random string (32byte) to use as Key and another (16byte) to use as IV for AES-256-CBC encryption using WinApi. The problem is that I need to save the generated string in a text file in order to manually test the decryption using OpenSSL in terminal. What can I use to generate the secure random string other than CryptGenRandom? The problem of CryptGenRandom is that it generates a random byte sequence that I can't save/use as OpenSSL input because it's not an ASCII text:
openssl aes-256-cbc -d -K "..." -iv ".." -in encrypted.txt
Is there an alternative?
This is my working code:
// handles for csp and key
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
BYTE *szKey = (BYTE*)calloc(DEFAULT_AES_KEY_SIZE + 1, sizeof(BYTE));
BYTE *szIV = (BYTE*)calloc(DEFAULT_IV_SIZE + 1, sizeof(BYTE));
char* ciphertext= 0;
DWORD dwPlainSize = lstrlenA(*plaintext), dwBufSize = 0;
AES256KEYBLOB AESBlob;
memset(&AESBlob, 0, sizeof(AESBlob));
// initalize key and plaintext
StrCpyA((LPSTR)szKey, "00112233445566778899001122334455");
StrCpyA((LPSTR)szIV, "4455667788990011");
// generate key & IV
//if (!CryptGenRandom(hProv, DEFAULT_AES_KEY_SIZE, szKey)) {goto error;}
//if (!CryptGenRandom(hProv, DEFAULT_IV_SIZE, szIV)) {goto error;}
// blob data for CryptImportKey() function (include key and version and so on...)
AESBlob.bhHdr.bType = PLAINTEXTKEYBLOB;
AESBlob.bhHdr.bVersion = CUR_BLOB_VERSION;
AESBlob.bhHdr.reserved = 0;
AESBlob.bhHdr.aiKeyAlg = CALG_AES_256;
AESBlob.dwKeySize = DEFAULT_AES_KEY_SIZE;
StrCpyA((LPSTR)AESBlob.szBytes, (LPCSTR)szKey);
// create a cryptographic service provider (CSP)
if (!CryptAcquireContextA(&hProv, NULL, MS_ENH_RSA_AES_PROV_A, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {goto error;}
// populate crypto provider (CSP)
if (!CryptImportKey(hProv, (BYTE*)&AESBlob, sizeof(AES256KEYBLOB), NULL, CRYPT_EXPORTABLE, &hKey)) { goto error; }
if (!CryptSetKeyParam(hKey, KP_IV, szIV, 0)) { goto error; }
// ciphertext allocation
dwBufSize = BUFFER_FOR_PLAINTEXT + dwPlainSize;
ciphertext = (char*)calloc(dwBufSize, sizeof(char));
memcpy_s(ciphertext, dwBufSize, *plaintext, dwPlainSize);
// encryption
if (!CryptEncrypt(hKey, NULL, TRUE, 0, (BYTE*)ciphertext, &dwPlainSize, dwBufSize) ) { goto error; }