CryptDeriveKey

【勇芳软件工作室】汉化HomePreviousNext

[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