CryptGenKey

The CryptGenKey function generates random cryptographic keys for use with the CSP module. A handle to the key is returned in phKey. This handle can then be used as needed with any of the other CryptoAPI functions requiring key handles.

The calling application is required to specify the algorithm when calling this function. Because this algorithm type is kept bundled with the key, the application does not need to specify the algorithm later when the actual cryptographic operations are performed.

The maximum size of an RSA signature key has been bumped up to 16,384 bits.

#include <wincrypt.h>
BOOL WINAPI CryptGenKey(
  HCRYPTPROV hProv,  // in
  ALG_ID Algid,      // in
  DWORD dwFlags,     // in
  HCRYPTKEY *phKey   // out
);
 

Parameters

hProv
Handle to the application's CSP. An application obtains this handle by using the CryptAcquireContext function.
Algid
Identifier for the algorithm for which the key is to be generated.

The valid values for this parameter will vary, depending on the CSP that is used. See the "Remarks" section for a list of possible algorithm identifiers.

dwFlags
Flags specifying the type of key generated.

The sizes of RSA signature and key exchange keys may be set when the key is generated. The key size is set with the upper 16 bits of the dwFlags parameter and these 16 bits represent the length of the key (modulus) in bits. So if a 2048 bit RSA signature key is to be generated then the value 0x08000000 would be combined together with the dwFlags parameter in bitwise OR operation. Notice that the upper 16 bits of 0x08000000 is 0x0800, or 2048 in decimal notation. If none of the upper 16 bits are set, then the default key size is generated. If a key larger than the max (16,384 signature, 512 key exchange) or smaller than the min (384 sig and key exchange) is given, the call fails with ERROR_INVALID_PARAMETER. For the parameters and limitations of keys generated using Microsoft providers, see Microsoft Cryptographic Service Providers.

This parameter can be zero, or you can specify one or more of the following flags by using the bitwise OR operator to combine them:

phKey
Address to which the function copies the handle of the newly generated key.

Return Values

If the function succeeds, the return value is TRUE. If it fails, the return value is FALSE. To retrieve extended error information, use the GetLastError function.

The following table lists the error codes most commonly returned by the GetLastError function. The error codes prefaced by "NTE" are generated by the particular CSP you are using.

Error code Description
ERROR_INVALID_HANDLE One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER One of the parameters contains an invalid value. This is most often an illegal pointer.
NTE_BAD_ALGID The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS The dwFlags parameter contains an invalid value.
NTE_BAD_UID The hProv parameter does not contain a valid context handle.
NTE_FAIL The function failed in some unexpected way.

Remarks

To generate a key to be used with a symmetric encryption algorithm (that is, a session key), use the Algid parameter to specify the algorithm. The algorithms available will most likely be different for each CSP. If you are using the Microsoft Base Cryptographic Provider, one of the following values can be used to specify the algorithm.

Value Description
CALG_RC2 RC2 block cipher
CALG_RC4 RC4 stream cipher

If you are using a Diffie-Hellman CSP, use one of the following values.

Value Description
CALG_DH_SF Specifies a "Store and Forward" Diffie-Hellman key.
CALG_DH_EPHEM Specifies an "Ephemeral" Diffie-Hellman key.

When keys are generated for symmetric block ciphers, the key by default will be set up in cipher block chaining (CBC) mode with an initialization vector of zero. This cipher mode provides a good default method for bulk encrypting data. To change these parameters, use the CryptSetKeyParam function.

In addition to generating keys for symmetric algorithms, the CryptGenKey function can also generate keys for public-key algorithms. The use of public-key algorithms is restricted to key exchange and digital signatures. Each CryptoAPI client generally possesses one key pair for each of these operations. To generate one of these key pairs, set the Algid parameter to one of the following values.

Value Description
AT_KEYEXCHANGE Key exchange
AT_SIGNATURE Digital signature

Note  When key specifications AT_KEYEXCHANGE and AT_SIGNATURE are specified for the Algid parameter, the algorithm identifiers that are used to generate the key depend on the provider used. As a result, for these key specifications, the values returned from CryptGetKeyParam (when the KP_ALGID parameter is specified) depend on the provider used. See ALG_ID to determine which algorithm identifier is used by the different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE.

Example

#include <wincrypt.h>

HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;

// Get a handle to user default provider.
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
    printf("Error %x during CryptAcquireContext!\n", GetLastError());
    goto done;
}

// Create a block cipher session key.
if(!CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey)) {
    printf("Error %x during CryptGenKey!\n", GetLastError());
    goto done;
}

// Use 'hKey' to encrypt or decrypt a message.
...

done:

// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Release the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);
 

Other examples are located in Encryption Example and Sender Code Example.

QuickInfo

  Windows NT: Requires version 4.0 or later.
  Windows: Requires Windows 95 OSR2 or later (or Windows 95 with IE 3.02 or later).
  Windows CE: Unsupported.
  Header: Declared in wincrypt.h.
  Import Library: Use advapi32.lib.

See Also

CryptAcquireContext, CryptDestroyKey, CryptExportKey, CryptGetKeyParam, CryptImportKey, CryptSetKeyParam