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
);
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.
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:
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.
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.
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. |
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.
#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.
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.
CryptAcquireContext, CryptDestroyKey, CryptExportKey, CryptGetKeyParam, CryptImportKey, CryptSetKeyParam