Importing Raw Cryptographic Keys

A version of this page is also available for

Windows Embedded CE 6.0 R3

4/8/2010

There are two occasions when it is necessary to import raw keys:

  • To save a session key for use by an application.
    For example, if your application encodes a database file, and you want your application to decode it later, then your application must store the session key. This is necessary because CSPs do not preserve symmetric keys between sessions.
  • To send a key to someone.
    It would be much easier for your application if the respective CSPs could communicate directly, but they cannot. This means that the key must be exported from your CSP, transmitted by your application to the destination application, and then imported to the destination CSP.

The following table details the functions you can use to create, configure, and destroy cryptographic keys, and to exchange them with other users.

Function Description

CryptDestroyKey

Destroys a key.

CryptExportKey

Exports a key from a CSP into a key BLOB in the application memory space.

CryptGenRandom

Generates random data, usually for salt values.

CryptGetKeyParam

Retrieves key parameters.

CryptGetUserKey

Gets a handle to the key exchange or signature key.

CryptImportKey

Imports a key from a key BLOB into a CSP.

CryptSetKeyParam

Specifies key parameters.

Example

Description

The following code example demonstrates how to import a raw key to use in subsequent operations.

Code

HRESULT CAACSCryptoProvider::InstallKey(__in_bcount(dwKeyLength) const BYTE * pbKey, DWORD dwKeyLength)
{
   HRESULT       hr = S_OK;
   BYTE * pbKeyData = NULL;

   struct INTPLAINTEXTKEYBLOB {
       BLOBHEADER bh;
       DWORD dwKeyLen;
   };

   pbKeyData = new BYTE[sizeof(INTPLAINTEXTKEYBLOB) + dwKeyLength];
   memset(pbKeyData, 0, sizeof(INTPLAINTEXTKEYBLOB) + dwKeyLength);

   INTPLAINTEXTKEYBLOB * pKeyBlob = reinterpret_cast<INTPLAINTEXTKEYBLOB *> (pbKeyData);

   // Initialize the header details.
   pKeyBlob->bh.bType    = PLAINTEXTKEYBLOB;
   pKeyBlob->bh.bVersion = CUR_BLOB_VERSION;    // Defined in wincrypt.h.
   pKeyBlob->bh.aiKeyAlg = CALG_AES_128;        // The type of key you are importing.
   pKeyBlob->dwKeyLen    = dwKeyLength;

   memcpy(pbKeyData + sizeof(INTPLAINTEXTKEYBLOB), pbKey, dwKeyLength);

    // Remove the previous key.
    if (m_hCurrentKey)                         // Initializing and destroying the key is a fairly simple task.
    {                                          // Given the nature of AACS AES usage for ECB, it is not worth 
        Hr = CryptDestroyKey(m_hCurrentKey);   // keeping an open table of keys. The Crypto Manager will make sure 
        m_hCurrentKey = NULL;                  // to only initialize a CBC key on the processing of the first block.
    }                                          // Support for multiple loaded keys is not required.

    // Import the key.
    result = CryptImportKey(g_hCryptProv, (const BYTE *) pbKeyData, sizeof(INTPLAINTEXTKEYBLOB) + dwKeyLength, NULL, 0, &m_hCurrentKey);

    delete[] pbKeyData;

    return hr;
}

Comments

To make the code example easier to read, security checking and error handling are not included. This code example should not be used in a release configuration unless it has been modified to include them.

See Also

Concepts

Microsoft Cryptographic System
Exporting Cryptographic Keys

Other Resources

Cryptography
Certificates