Simple AES Encryption Using WinAPI

I need to do a simple one-block AES encryption / decryption in my Qt / C ++ application. This is an "honest honest implementation", therefore only basic encrypt(key, data) is needed - I do not worry about initialization vectors, etc. My input and key will always be exactly 16 bytes.

I would really like to avoid another dependency for compiling / linking / submitting with my application, so I am trying to use what is available on each platform. On a Mac, it was one liner before CCCrypt . On Windows, I get lost in the WinCrypt.h API. Their file encryption example is nearly 600 lines. Seriously?

I look at CryptEncrypt , but I fall into a rabbit hole of dependencies that you must create before you can call it.

Can someone provide a simple example of using AES encryption using the Windows API? Of course, there is a way to do this in a line or two. Suppose you already have a 128-bit key and 128-bit data for encryption.

+6
source share
1 answer

Here is the best I could come up with. Suggestions for improvement are welcome!

 static void encrypt(const QByteArray &data, const QByteArray &key, QByteArray *encrypted) { // Create the crypto provider context. HCRYPTPROV hProvider = NULL; if (!CryptAcquireContext(&hProvider, NULL, // pszContainer = no named container NULL, // pszProvider = default provider PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { throw std::runtime_error("Unable to create crypto provider context."); } // Construct the blob necessary for the key generation. AesBlob128 aes_blob; aes_blob.header.bType = PLAINTEXTKEYBLOB; aes_blob.header.bVersion = CUR_BLOB_VERSION; aes_blob.header.reserved = 0; aes_blob.header.aiKeyAlg = CALG_AES_128; aes_blob.key_length = kAesBytes128; memcpy(aes_blob.key_bytes, key.constData(), kAesBytes128); // Create the crypto key struct that Windows needs. HCRYPTKEY hKey = NULL; if (!CryptImportKey(hProvider, reinterpret_cast<BYTE*>(&aes_blob), sizeof(AesBlob128), NULL, // hPubKey = not encrypted 0, // dwFlags &hKey)) { throw std::runtime_error("Unable to create crypto key."); } // The CryptEncrypt method uses the *same* buffer for both the input and // output (!), so we copy the data to be encrypted into the output array. // Also, for some reason, the AES-128 block cipher on Windows requires twice // the block size in the output buffer. So we resize it to that length and // then chop off the excess after we are done. encrypted->clear(); encrypted->append(data); encrypted->resize(kAesBytes128 * 2); // This acts as both the length of bytes to be encoded (on input) and the // number of bytes used in the resulting encrypted data (on output). DWORD length = kAesBytes128; if (!CryptEncrypt(hKey, NULL, // hHash = no hash true, // Final 0, // dwFlags reinterpret_cast<BYTE*>(encrypted->data()), &length, encrypted->length())) { throw std::runtime_error("Encryption failed"); } // See comment above. encrypted->chop(length - kAesBytes128); CryptDestroyKey(hKey); CryptReleaseContext(hProvider, 0); } 
+4
source

Source: https://habr.com/ru/post/900638/


All Articles