Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

This function generates cryptographic session keys derived from base data. This function guarantees that all keys generated from the same base data are identical, provided the same cryptographic service provider (CSP) and algorithms are used. The base data can be a password or any other user data.

This function is the same as the CryptGenKeyfunction, except that the generated session keys are derived from base data instead of being random. The CryptDeriveKeyfunction can only generate session keys and cannot be used to generate public/private key pairs.

A handle to the session key is returned in the phKeyparameter. This handle can then be used with any CryptoAPI functions that require key handles.

Syntax

BOOL CRYPTFUNC CryptDeriveKey( 
  HCRYPTPROV 
hProv, 
  ALG_ID 
Algid, 
  HCRYPTHASH 
hBaseData, 
  DWORD 
dwFlags, 
  HCRYPTKEY* 
phKey
);

Parameters

hProv

[in] HCRYPTPROVhandle to a CSP created by a call to the CryptAcquireContextfunction.

Algid

[in] ALG_IDidentifier of the algorithm for the generated key. The valid value for this parameter varies depending on the CSP. Common hash algorithm identifiers are: CALG_AES_128, CALG_AES_192, CALG_AES_256, CALG_RSA_SIGN, CALG_RSA_KEYX, CALG_RC2, CALG_RC4, CALG_RC5, CALG_DES, CALG_3DES_112, and CALG_3DES. See ALG_IDfor definitions.

hBaseData

[in] HCRYPTHASHhandle to a hash object that contains the exact base data.

To obtain this handle, an application must first create a hash object with the CryptCreateHashfunction and then add the base data to the hash object with the CryptHashDatafunction. For more information about hashing and digital signatures, see the programmer's guide topics under Cryptography.

dwFlags

[in] Specifies the type of key generated.

The sizes of a session key can be set when the key is generated. The key size, representing the length of the key modulus in bits, is set with the upper 16 bits of this parameter. Thus, if a 128-bit RC4 session key is to be generated, the value 0x00800000 is combined with any other dwFlagspredefined value with a bitwise-OR operation. Due to changing export control restrictions, the default CSP and default key length may change between operating system releases. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set using the dwFlagsparameter to ensure interoperability on different operating system platforms.

This parameter can be zero. The following table shows flags that you can specify. You can use the bitwise ORoperator to combine flags.

Value Description

CRYPT_EXPORTABLE

If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKeyfunction. Because keys generally must be exportable, this flag should usually be set.

If this flag is not set, the session key will not be exportable. This means the key will be available only within the current session and only to the application that created it.

This flag does not apply to public/private key pairs.

CRYPT_CREATE_SALT

Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value is 128 bits and the session key is 40 bits, there will be 88 bits left over.

If this flag is set, the key is assigned a salt value based on the unused hash value bits. You can retrieve this salt value by using the CryptGetKeyParamfunction with the dwParamparameter set to KP_SALT.

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

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

CRYPT_NO_SALT

Specifies that no salt value gets allocated for a 40-bit symmetric key.

CRYPT_USER_PROTECTED

If this flag is set, the user is notified through a dialog box or another method when certain actions are attempted by using this key. The precise behavior is specified by the CSP being used.

CRYPT_UPDATE_KEY

Some CSPs use session keys derived from multiple hash values, in which case CryptDeriveKeymust be called multiple times.

If this flag is set, a new session key is not generated. Instead, the key specified by phKeyis modified. The precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used.

The Microsoft Cryptographic Providers ignore this flag.

phKey

[out] Pointer to the HCRYPTKEYhandle to the newly generated key.

Return Value

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

The following table shows the common values for the GetLastErrorfunction. 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 Algidparameter specifies an algorithm that this CSP does not support.

NTE_BAD_FLAGS

The dwFlagsparameter contains an invalid value.

NTE_BAD_HASH

The hBaseDataparameter does not contain a valid handle to a hash object.

NTE_BAD_HASH_STATE

An attempt was made to add data to a hash object that is already marked as finished.

NTE_BAD_UID

The hProvparameter does not contain a valid context handle.

NTE_FAIL

The function failed in some unexpected way.

Remarks

To generate a key for a symmetric encryption algorithm, use the Algidparameter to specify the algorithm. The algorithms available will most likely be different for each CSP.

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

After the CryptDeriveKeyfunction has been called, no more data can be added to the hash object. The CryptDestroyHashfunction should be called at this point to destroy the hash object.

Example Code

Copy Code
#include <wincrypt.h>
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTHASH hHash = 0;
CHAR szPassword[ ] = "apple-camshaft";
DWORD dwLength;
// Get a handle to user default provider using CryptAcquireContext.
// For sample code, see <A
HREF="wce50lrfcryptacquirecontext.htm">CryptAcquireContext</A>.
...
// Create a hash object.
if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
 printf("Error %x during CryptCreateHash!\n", GetLastError());
 goto done;
}
// Hash the password string.
dwLength = strlen(szPassword);
if(!CryptHashData(hHash, (BYTE *)szPassword, dwLength, 0)) {
 printf("Error %x during CryptHashData!\n", GetLastError());
 goto done;
}
// Create a block cipher session key based on the hash of the
password.
if(!CryptDeriveKey(hProv, CALG_RC2, hHash, CRYPT_EXPORTABLE,
&hKey)) {
 printf("Error %x during CryptDeriveKey!\n", GetLastError());
 goto done;
}
// Use 'hKey' to encrypt or decrypt a message.
...
done:
// Destroy the hash object.
if(hHash != 0) CryptDestroyHash(hHash);
// Destroy the session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Free the provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);

Requirements

Header wincrypt.h
Library coredll.lib
Windows Embedded CE Windows CE 2.10 and later
Windows Mobile Windows Mobile Version 5.0 and later

See Also