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
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
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
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 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
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 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
CALG_RC4 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
Once the CryptDeriveKey
function has been called, no more data can be added to the hash object. The CryptDestroyHash
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
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