CryptGenKey

This function generates random cryptographic keys for use with the cryptographic service provider (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.

When calling this function, the application is required to 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.

The maximum size of an RSA signature is 16,384 bits.

At a Glance

Header file: Wincrypt.h
Windows CE versions: 2.10 and later

Syntax

BOOL CRYPTFUN CryptGenKey( HCRYPTPROV hProv, ALG_ID Algid,
DWORD dwFlags, HCRYPTKEY *phKey );

Parameters

hProv

[in] Handle to the application's CSP. An application obtains this handle by using the CryptAcquireContext function.

Algid

[in] 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 common algorithm identifiers.

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

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:

Flag Description
CRYPT_EXPORTABLE. If this flag is set, then 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, then 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, then 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, then the key will be given a salt value of zero.
When keys with nonzero salt values are exported (through CryptExportKey), then 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 Windows CE Cryptographic Providers ignore this flag.
CRYPT_PREGEN. Specifies an initial Diffie-Hellman or DSS key generation. Useful only with Diffie-Hellman/DSS CSPs.

phKey

[out] Address to which the function copies the handle of the newly generated key.

Return Values

TRUE indicates success. FALSE indicates failure. To get extended error information, call GetLastError. Common values for GetLastError are described in the following table. 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.

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 the Microsoft Enhanced Cryptographic Provider, you can additionally use the following values

Value Description
CALG_DES DES block cipher
CALG_3DES Triple DES block cipher
CALG_3DES_112 Triple DES two key block 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.

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

See Also

CryptAcquireContext, CryptDestroyKey, CryptExportKey, CryptGetKeyParam, CryptImportKey, CryptSetKeyParam