This function generates a random cryptographic session key or a public/private key pair for use with the cryptographic service provider (CSP) module. The function returns a handle to the key in the phKey parameter. This handle can then be used as needed with any of the other CryptoAPI functions requiring a key handle.

When calling this function, the application must specify the algorithm. 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.



  • hProv
    [in] HCRYPTPROV handle to a CSP created by a call to CryptAcquireContext.

  • Algid
    [in] ALG_ID structure identifying the algorithm for the key to be generated.

    To generate a session key to be used with a symmetric encryption algorithm, use the Algid parameter to specify the algorithm. The valid values for this parameter vary depending on the CSP.

    The following table shows the common algorithm identifiers.

    Value Description
    CALG_AGREEDKEY_ANY Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys
    CALG_CYLINK_MEK An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make its key length 64 bits
    CALG_DES DES encryption algorithm
    CALG_DESX DES encryption algorithm
    CALG_3DES Triple DES encryption algorithm
    CALG_3DES_112 Triple DES encryption algorithm using two 112 bit keys
    CALG_DH_EPHEM Diffie-Hellman ephemeral key exchange algorithm
    CALG_DH_SF Diffie-Hellman store and forward key exchange algorithm
    CALG_DSS_SIGN DSA public-key signature algorithm
    CALG_RC2 RC2 block encryption algorithm
    CALG_RC4 RC4 stream encryption algorithm
    CALG_RC5 RC5 block encryption algorithm
    CALG_SKIPJACK Skipjack block encryption algorithm (FORTEZZA)
    CALG_SSL3_SHAMD5 SSL3 client authentication

    In addition to generating keys for symmetric algorithms, the CryptGenKey function can 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. The following table shows values for the Algid parameter that generate these key pairs.

    Value Description
    AT_KEYEXCHANGE Key exchange
    AT_SIGNATURE Digital signature

    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 the CryptGetKeyParam function, when the KP_ALGID parameter is specified, depend on the provider used.

  • dwFlags
    [in] Specifies 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, or 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 is given that is larger than the maximum 16,384 signature and 512 key exchange or smaller than the minimum 384 signature and key exchange, the call fails with ERROR_INVALID_PARAMETER.

    The following table shows flags that you can specify. You can use the bitwise OR operator to combine flags.

    Flag Description
    CRYPT_EXPORTABLE If this flag is set, the key can be transferred out of the CSP into a key BLOB by using the CryptExportKey function. Because session keys generally must be exportable, this flag should usually be set when they are created.

    If this flag is not set, the key will not be exportable. For a session key, this means that the key will be available only within the current session and only the application that created it will be able to use it. For a public/private key pair, this means that the private key cannot be transported or backed up.

    This flag applies only to session key and private key BLOBs. It does not apply to public keys, which are always exportable.

    CRYPT_CREATE_SALT If this flag is set, the key will be assigned a random salt value automatically. You can retrieve this salt value by using the CryptGetKeyParam function with the dwParam parameter set to KP_SALT.

    If this flag is not set, the key will be given a salt value of zero.

    When keys with nonzero salt values are exported through CryptExportKey, the salt value must also be obtained and kept with the key BLOB.

    CRYPT_NO_SALT Specifies that a no salt value gets allocated for a 40-bit symmetric key.
    CRYPT_USER_PROTECTED The Microsoft cryptographic service providers ignore this flag.
    CRYPT_PREGEN. Specifies an initial Diffie-Hellman or DSS key generation. Useful only with Diffie-Hellman/DSS CSPs.

    This parameter can be zero.

  • phKey
    [out] Pointer to the HCRYPTKEY handle to the newly generated key.

Return Values

TRUE indicates success. FALSE indicates failure. To get extended error information, call the GetLastError function.

The following table describes the common values for the GetLastError function. The error values prefaced by NTE are generated by the particular CSP you are using.

Value 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.
NTE_SILENT_CONTEXT The provider could not perform the action because the context was acquired as silent.


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

To choose an appropriate key length, the following methods are recommended:

  • Enumerate the algorithms that the CSP supports and get the maximum and minimum key lengths for each algorithm.
  • Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length because this can lead to performance issues.
  • After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length.

Example Code

#include <wincrypt.h>


// Get a handle to user default provider.
// Call CryptAcquireContext. For sample code, see CryptAcquireContext.

// 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.


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


OS Versions: Windows CE 2.10 and later.
Header: Wincrypt.h.
Link Library: Coredll.lib.

See Also

CryptAcquireContext | CryptDestroyKey | CryptExportKey | CryptGetKeyParam | CryptImportKey | CryptSetKeyParam

 Last updated on Thursday, April 08, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.