[New - Windows NT]
[New - Windows 95, OEM Service Release 2]
CryptDeriveKey函数生成从基础数据导出的加密密钥。该函数保证从相同的基本数据生成的所有密钥将相同,只要使用相同的CSP和算法即可。基本数据可以是密码或任何其他用户数据。
此函数与CryptGenKey相同,只是生成的会话密钥来自基本数据而不是随机的。另一个区别是CryptDeriveKey函数不能用于生成公钥/私钥对。
会话密钥的句柄在【phKey】中返回。然后可以根据需要使用任何其他需要密钥句柄的CryptoAPI函数。
BOOL CRYPTFUNC CryptDeriveKey(
HCRYPTPROV【pbBuffer】, | |
ALG_ID【寒冷的】, | |
HCRYPTHASH【hBaseData】, | |
DWORD【dwFlags中】, | |
HCRYPTKEY *【phKey】 | |
); |
参数
【pbBuffer】
[in]应用程序的CSP的句柄。应用程序使用CryptAcquireContext函数获取此句柄。
【寒冷的】
[in]要生成密钥的算法的标识符。
此参数的有效值将有所不同,具体取决于所使用的CSP。有关可能的算法标识符的列表,请参阅“备注”部分。
【hBaseData】
[in]已准确提供基本数据的哈希对象的句柄。
要获取此句柄,应用程序必须首先使用CryptCreateHash创建哈希对象,然后使用CryptHashData将基础数据添加到哈希对象。该过程在哈希和数字签名部分中有详细描述。
【dwFlags中】
[in]指定生成的密钥类型的标志。该参数可以为零,或者您可以使用二元OR运算符来组合它们来指定以下一个或多个标志。
CRYPT_EXPORTABLE
如果设置了该标志,则会话密钥可以通过CryptExportKey功能从CSP传送到密钥库中。由于密钥通常必须可导出,因此通常应该设置该标志。
如果此标志未设置,则会话密钥将【不】可导出。这意味着密钥只能在当前会话中可用,只有创建它的应用才能使用它。
此标志不适用于公钥/私钥对。
CRYPT_CREATE_SALT
通常,当从哈希值产生会话密钥时,存在多个剩余比特。例如,如果哈希值是128位,而会话密钥是40位,那么剩下的是88位。
如果设置了该标志,则将根据未使用的散列值位分配一个盐值。您可以使用CryptGetKeyParam功能将【dwParam】参数设置为KP_SALT来检索此盐值。
如果未设置此标志,则键值将为零。
导出具有非零盐值的键(使用CryptExportKey)时,还必须获取盐值并使用键blob保存。
CRYPT_USER_PROTECTED
如果设置了此标志,则当使用此键尝试某些操作时,将通过对话框或其他方法通知用户。精确的行为由使用的CSP指定。
Microsoft RSA基础提供程序忽略此标志。
CRYPT_UPDATE_KEY
一些CSP使用从多个哈希值导出的会话密钥。在这种情况下,必须多次调用CryptDeriveKey.
如果设置了此标志,则不会生成新的会话密钥。相反,修改了【phKey】指定的密钥。该标志的精确行为取决于正在生成的键的类型和正在使用的特定CSP。
Microsoft RSA基础提供程序忽略此标志。
【phKey】
[in/out]功能复制新生成的键的句柄的地址。
备注
要生成对称加密算法的密钥,请使用【寒冷的】参数指定算法。可用的算法对于每个CSP最有可能是不同的。如果您使用的是Microsoft RSA Base Provider,请使用以下值之一来指定算法:
* __ CALG_RC2 RC2块密码
* __ CALG_RC4 RC4流加密
当为对称块密码生成密钥时,默认情况下,密钥将以密码块链接(CBC)模式设置,初始化向量为零。此密码模式为批量加密数据提供了良好的默认方法。要更改这些参数,请使用CryptSetKeyParam功能。
一旦调用了CryptDeriveKey函数,就不会有更多的数据被添加到哈希对象。此时应调用CryptDestroyHash函数来销毁哈希对象。
返回值
如果函数成功,返回值不为零。
如果函数失败,返回值为零。要检索扩展错误信息,请使用GetLastError功能。
下表列出了GetLastError函数最常返回的错误代码。由“NTE”开头的错误代码由您使用的特定CSP生成。
错误 | 描述 |
ERROR_INVALID_HANDLE | 其中一个参数指定一个无效句柄。 |
ERROR_INVALID_PARAMETER | 其中一个参数包含无效值。这通常是一个非法的指针。 |
NTE_BAD_ALGID | 【寒冷的】参数指定此CSP不支持的算法。 |
NTE_BAD_FLAGS | 【dwFlags中】参数包含无效值。 |
NTE_BAD_HASH | 【hBaseData】参数不包含哈希对象的有效句柄。 |
NTE_BAD_UID | 【pbBuffer】参数不包含有效的上下文句柄。 |
NTE_FAIL | 该函数以某种意想不到的方式失败。 |
例
#include < wincrypt.h >
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTHASH hHash = 0;
CHAR szPassword[ ] = "apple-camshaft";
DWORD dwLength;
//获取用户默认提供程序的句柄。
if(!CryptAcquireContext(& hProv,NULL,NULL,PROV_RSA_FULL,0)){
printf("Error %x during CryptAcquireContext!\n", GetLastError());
goto done;
}
//创建哈希对象。
IF(!CryptCreateHash(hProv,CALG_MD5,0,0,{} hHash 989796005)){
printf("Error %x during CryptCreateHash!\n", GetLastError());
goto done;
}
//哈希密码字符串。
dwLength = strlen(szPassword);
if(!CryptHashData(hHash,(BYTE *)szPassword,dwLength,0)){
printf("Error %x during CryptHashData!\n", GetLastError());
goto done;
}
//根据密码的哈希创建块密码会话密钥。
IF(!CryptDeriveKey(hProv,CALG_RC2,hHash,CRYPT_EXPORTABLE,{}的hKey 989796005)){
printf("Error %x during CryptDeriveKey!\n", GetLastError());
goto done;
}
//使用'hKey'来做某事
...
完成:
//销毁哈希对象。
if(hHash != 0) CryptDestroyHash(hHash);
//销毁会话密钥。
if(hKey != 0) CryptDestroyKey(hKey);
//发布提供者句柄。
if(hProv != 0) CryptReleaseContext(hProv, 0);
也可以看看
CryptAcquireContext, CryptCreateHash, CryptDestroyHash, CryptDestroyKey, CryptExportKey, CryptGenKey, CryptGetKeyParam, CryptHashData, CryptSetKeyParam