Importing secret key in CryptoAPI

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);

}

Leave a Reply