|  | Overview |  | 
|  | 
|  | Group |  | 
|  | 
|  | Quick Info 
 | Windows NT 
 | Yes 
 |  | Win95 
 | OSR2 
 |  | Win32s 
 | No 
 |  | Import Library 
 | advapi32.lib 
 |  | Header File 
 | wincrypt.h 
 |  | Unicode 
 | WinNT 
 |  | Platform Notes 
 | None 
 | 
 |  | 
 
CryptDeriveKey
[New - Windows NT]
[New - Windows 95, OEM Service Release 2]
The 
CryptDeriveKey function generates cryptographic keys derived from base data. This function
guarantees that all keys generated from the same base data will be identical,
provided the same CSP and algorithms are used. The base data can be a password or
any other user data.
This function is the same as 
CryptGenKey, except that the generated session keys are derived from base data instead of
being random. Another difference is that the 
CryptDeriveKey function cannot be used to generate public/private key pairs.
A handle to the session key is returned in 
phKey. This handle can then be used as needed with any of the other CryptoAPI
functions that require key handles.
BOOL CRYPTFUNC CryptDeriveKey(
| HCRYPTPROV hProv, 
 | 
 | 
| ALG_ID Algid, 
 | 
 | 
| HCRYPTHASH hBaseData, 
 | 
 | 
| DWORD dwFlags, 
 | 
 | 
| HCRYPTKEY *phKey 
 | 
 | 
| ); 
 | 
 | 
 
Parameters
hProv
[in] A handle to the application's CSP. An application obtains this handle
using the 
CryptAcquireContext function.
Algid
[in] The 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 possible algorithm identifiers.
hBaseData
[in] A handle to a hash object that has been fed exactly the base data.
To obtain this handle, an application must first create a hash object with 
CryptCreateHash and then add the base data to the hash object with 
CryptHashData. This process is described in detail in the section 
Hashes and Digital Signatures.
dwFlags
[in] The flags specifying the type of key generated. This parameter can be
zero, or you can specify one or more of the following flags, using the binary OR
operator to combine them.
CRYPT_EXPORTABLE
If this flag is set, then the session key can be transferred out of the CSP
into a key blob through the 
CryptExportKey function. Because keys generally must  be exportable, this flag should
usually be set.
If this flag is not set, then the session key will 
not be exportable. This means the key will only be available within the current
session and only the application that created it will be able to use 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 leftover.
If this flag is set, then the key will be assigned a salt value based on the
unused hash value bits. You can retrieve this salt value 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 (using 
CryptExportKey), the salt value must also be obtained  and kept with the key blob.
CRYPT_USER_PROTECTED
If this flag is set, then the user will be notified through a dialog box or
another method when certain actions are attempted using this key. The precise
behavior is specified by the CSP being used. 
The Microsoft RSA Base Provider ignores this flag.
CRYPT_UPDATE_KEY
Some CSPs use session keys that are derived from multiple hash values. When
this is the case, 
CryptDeriveKey must be called multiple times.
If this flag is set, a new session key is not generated. Instead, the key
specified by 
phKey is 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 RSA Base Provider ignores this flag.
phKey
[in/out] The address to which the function copies the handle of the newly
generated key.
 
Remarks
To generate a key for a symmetric encryption algorithm, 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 RSA Base Provider,
use one of the following values to specify the algorithm:
-  CALG_RC2  RC2 block cipher RC2 block cipher
-  CALG_RC4  RC4 stream cipher RC4 stream cipher
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.
Once the 
CryptDeriveKey function has been called, no more data can be added to the hash object. The 
CryptDestroyHash function should be called at this point to destroy the hash object.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. 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 
 | 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_HASH 
 | The hBaseData parameter does not contain a valid handle to a hash object. 
 | 
| NTE_BAD_UID 
 | The hProv parameter does not contain a valid context handle. 
 | 
| NTE_FAIL 
 | The function failed in some unexpected way. 
 | 
 
Example
#include <wincrypt.h>
  
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTHASH hHash = 0;
CHAR szPassword[ ] = "apple-camshaft";
DWORD dwLength;
// Get handle to user default provider.
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
    printf("Error %x during CryptAcquireContext!\n", GetLastError());
    goto done;
}
// Create hash object.
if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
    printf("Error %x during CryptCreateHash!\n", GetLastError());
    goto done;
}
// Hash password string.
dwLength = strlen(szPassword);
if(!CryptHashData(hHash, (BYTE *)szPassword, dwLength, 0)) {
    printf("Error %x during CryptHashData!\n", GetLastError());
    goto done;
}
// Create block cipher session key based on 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 do something.
...
  
done:
// Destroy hash object.
if(hHash != 0) CryptDestroyHash(hHash);
// Destroy session key.
if(hKey != 0) CryptDestroyKey(hKey);
// Release provider handle.
if(hProv != 0) CryptReleaseContext(hProv, 0);
 
See Also
CryptAcquireContext, 
CryptCreateHash, 
CryptDestroyHash, 
CryptDestroyKey, 
CryptExportKey, 
CryptGenKey, 
CryptGetKeyParam, 
CryptHashData, 
CryptSetKeyParam
			
				- Software for developers
				
- 
				Delphi Components
 .Net Components
 Software for Android Developers
- More information resources
				
- 
				MegaDetailed.Net
 Unix Manual Pages
 Delphi Examples