# CryptGenKey

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.

```
BOOL CRYPTFUNC CryptGenKey( HCRYPTPROVhProv,ALG_IDAlgid,DWORDdwFlags,HCRYPTKEY* phKey);
```

#### Parameters

*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 CALG_TEK TEK (FORTEZZA) 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. |

#### Remarks

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>
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
// 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.
...
done:
// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Release the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);
```

#### Requirements

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