This texts explains how to use your own generated secret key for symmetric ciphers which are available in CryptoAPI. There are some examples/tutorials for generating and exporting secret keys in CryptoAPI, but I have found a lack of materials regarding importing pre generated keys. The code I’m going to comment here is an example of DES enciphering but actually you can use this technique for any symmetric cipher in CryptoAPI because they all have the same interface in term of function calls. I have not tried to optimize this code or at least to make it look good but I hope it is clear from this example how to use some of the useful functions.
So let’s see what we have.
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void main(void){
HCRYPTPROV hCryptProv;
DWORD dwUserNameLen = 100;
LPCSTR UserName= NULL;
HCRYPTKEY hKey;
BYTE output[16];
UINT * out = ((UINT*) &output[0]);
BYTE bKey[20];
DWORD keyLen = 8;
DWORD dataLen = 8;
int i;
//This is the data we will be enciphering
BYTE data[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
//Our secret key to be used in encryption
BYTE key[8] = {0x13, 0x34, 0x57, 0x79, 0x9B, 0xBC, 0xDF, 0xF1};
//Initialization vector in case you
//would use any other mode except ECB
BYTE IV[8] = {0, 0, 0, 0, 0, 0, 0, 0};
BLOBHEADER keyHeader;
keyHeader.bType = PLAINTEXTKEYBLOB;
keyHeader.bVersion = CUR_BLOB_VERSION;
keyHeader.reserved = 0;
keyHeader.aiKeyAlg = CALG_DES;
//Initializing
CryptAcquireContext(&hCryptProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL, 0);
//move keyHeader into buffer
for(i=0; i<sizeof(keyHeader); i++){
bKey[i] = *((BYTE*) &keyHeader + i);
}
//move keySize into buffer
for(i=0; i<sizeof(keyLen); i++){
bKey[i + sizeof(keyHeader)] = *((BYTE*) &keyLen + i);
}
//move key bytes into buffer
for(i=0; i<8; i++){
bKey[i + sizeof(keyHeader) + sizeof(keyLen)] = key[i];
}
//Here is the main part of this example
//Import key BLOB
CryptImportKey(hCryptProv,
(BYTE*) &bKey,
sizeof(keyHeader) + sizeof(DWORD) + 8,
0, 0, &hKey);
//set DES mode
DWORD desMode = CRYPT_MODE_ECB;
CryptSetKeyParam(hKey, KP_MODE, (BYTE*) &desMode, 0);
//set initialization vector
//though for
CryptSetKeyParam(hKey, KP_IV, &IV[0], 0);
//here is the encryption function
CryptEncrypt(hKey, 0, FALSE, 0, (BYTE*) &data[0], &dataLen, 8);
//move output back to the buffer
for(i=0;i<16;i++){
output[i] = *(((BYTE*) &data)+i);
}
//Free resources
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}