CryptGetProvParam

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

[New - Windows NT]

[New - Windows 95, OEM Service Release 2]

CryptGetProvParam功能允许应用程序检索管理CSP操作的参数。

BOOL CRYPTFUNC CryptGetProvParam(

HCRYPTPROV【pbBuffer】, 
DWORD【dwParam】, 
BYTE *【pbData】, 
DWORD *【pdwDataLen】, 
DWORD【dwFlags中】 
); 

参数

【pbBuffer】

[in]查询参数的CSP的句柄。

【dwParam】

[in]参数号。有关参数的列表,请参阅“备注”部分。

【pbData】

[out]参数数据缓冲区。该函数将指定的参数数据复制到此缓冲区。此数据的形式将根据参数编号而有所不同。

如果您正在做的是确定返回的参数数据所需的字节数,则此参数可以为NULL。

【pdwDataLen】

[in/out]参数数据长度的地址。在调用此函数之前,调用者应将此参数设置为【pbData】缓冲区的长度(以字节为单位)。返回时,该地址将包含复制到缓冲区的参数数据的字节数。

如果由【pbData】指定的缓冲区不足以容纳数据,该函数将通过GetLastError函数返回ERROR_MORE_DATA错误代码,并将所需的缓冲区大小以字节存储到【pdwDataLen】指向的变量中。

如果【pbData】为NULL,则不会返回任何错误,该函数将数据的大小存储在【pdwDataLen】所指向的变量中。

注意当读取其中一个枚举参数(PP_ENUMALGS或PP_ENUMCONTAINERS)时,【pdwDataLen】参数的工作方式略有不同。如果【pbData】为NULL或指向【pdwDataLen】的值太小,则此参数中返回的值是枚举列表中最大项目的大小,而不是当前正在读取的项目的大小。

当读取其中一个枚举参数并且【pbData】参数为NULL时,必须指定CRYPT_FIRST标志,以便正确检索大小信息。

【dwFlags中】

[in]标志值。此参数通常设置为零。

当其中一个枚举参数(PP_ENUMALGS或PP_ENUMCONTAINERS)被读取时,可以指定CRYPT_FIRST标志。设置此标志时,将返回枚举列表中的第一个项目。如果未设置此标志,则返回列表中的下一个项目。

备注

参数号

【dwParam】参数可以设置为以下值之一:

PP_CONTAINER

关键容器名称。指定此参数时,该函数使用当前密钥容器的名称填充【pbData】缓冲区。该名称采用零终止CHAR字符串的形式。

该字符串与CryptAcquireContext函数的【pszContainer】参数中传递的字符串完全相同,以便指定使用当前的密钥容器。通常读取此参数以确定默认密钥容器的名称。

PP_ENUMALGS

算法信息。当指定此参数时,该函数使用CSP支持的算法之一填充【pbData】缓冲区。必须重复读取PP_ENUMALGS参数,以枚举所有支持的算法。算法没有以任何特定顺序列举。

首次读取PP_ENUMALGS参数时,应指定CRYPT_FIRST标志。这将确保返回枚举列表中有关“第一”算法的信息。然后可以重复读取PP_ENUMALGS参数,以便检索有关其余算法的信息。当CryptGetProvParam功能失败并出现ERROR_NO_MORE_ITEMS时,则已到达枚举列表的结尾。示例说明的代码示例位于“示例”部分。

以下代码片段指示函数在【pbData】缓冲区中返回的数据格式。

ALG_ID aiAlgid;

DWORD dwBits;

DWORD dwNameLen;

CHAR szName[dwNameLen];

下表定义了每个这些字段。

领域描述
The algorithm identifier.算法标识符。en这是传递给CryptGenKeyCryptDeriveKeyCryptCreateHash 函数的值,以便指定使用特定的算法。
The number of bits in the keys used by the algorithm.算法使用的密钥中的比特数。

如果这是散列算法,则该值指示由该算法生成的哈希值中的比特数。

dwNameLen算法名称中的字符数,包括终止零。
szName的算法的零终止名称。

PP_ENUMCONTAINERS

关键容器名称。指定此参数时,该函数将使用CSP维护的其中一个密钥容器的名称填充【pbData】缓冲区。该名称以零终止的CHAR字符串的形式。必须重复读取PP_ENUMCONTAINERS参数才能枚举所有容器名称。

这些容器名称的枚举方式与CSP支持的算法相同。有关详细信息,请参阅PP_ENUMALGS。

PP_IMPTYPE

CSP实现类型。【pbData】缓冲区将包含一个DWORD值,表示CSP如何实现。可能的值是:

*CRYPT_IMPL_HARDWARE

*CRYPT_IMPL_SOFTWARE

*CRYPT_IMPL_MIXED

* CRYPT_IMPL_UNKNOWN(CSP没有告诉)

PP_NAME

CSP名称。指定此参数时,该函数使用CSP的名称填充【pbData】缓冲区。该名称采用零终止CHAR字符串的形式。

该字符串与CryptAcquireContext函数的【pszProvider】参数中传递的字符串相同,以便指定使用当前CSP。例如,当读取此参数时,Microsoft RSA Base Provider将返回“Microsoft Base Cryptographic Provider v1.0”。

PP_VERSION

CSP版本号。【pbData】缓冲区将包含一个DWORD值,表示CSP的版本号。最低有效字节包含副版本号和主版本号的下一个最高有效字节。例如,版本1.0将在这里表示为0x00000100。

算法标识符

当枚举算法时,您的应用程序可能需要确定特定算法的类。例如,您可能希望向用户显示加密算法列表,并忽略其余的。这可以通过GET_ALG_CLASS(x)宏来完成。该宏将算法标识符作为参数,并返回指示标识符所属的算法的一般类别的代码。可能的返回值包括:

*ALG_CLASS_DATA_ENCRYPT

*ALG_CLASS_HASH

*ALG_CLASS_KEY_EXCHANGE

*ALG_CLASS_SIGNATURE

下表列出了Microsoft RSA Base Provider支持的算法以及每个算法的类别。

名称识别码
"MD2"CALG_MD2ALG_CLASS_HASH
"MD5"CALG_MD5ALG_CLASS_HASH
"SHA"CALG_SHAALG_CLASS_HASH
"MAC"CALG_MACALG_CLASS_HASH
"RSA_SIGN"CALG_RSA_SIGNALG_CLASS_SIGNATURE
"RSA_KEYX"CALG_RSA_KEYXALG_CLASS_KEY_EXCHANGE
"RC2"CALG_RC2ALG_CLASS_DATA_ENCRYPT
"RC4"CALG_RC4ALG_CLASS_DATA_ENCRYPT

如果您的应用程序不识别算法标识符,则不建议使用该算法。使用未知的加密算法有时会产生不可预知的结果。

返回值

如果函数成功,返回值不为零。

如果函数失败,返回值为零。要检索扩展错误信息,请使用GetLastError功能。

下表列出了GetLastError函数最常返回的错误代码。由“NTE”开头的错误代码由您使用的特定CSP生成。

错误描述
ERROR_INVALID_HANDLE其中一个参数指定一个无效句柄。
ERROR_INVALID_PARAMETER其中一个参数包含无效值。这通常是一个非法的指针。
ERROR_NO_MORE_ITEMS枚举列表的结尾已经到达。【pbData】缓冲区中没有有效的数据。仅当【dwParam】等于PP_ENUMALGS或PP_ENUMCONTAINERS时才返回此错误。
NTE_BAD_FLAGS【dwFlags中】参数不为零。
NTE_BAD_TYPE【dwParam】参数指定未知参数号。
NTE_BAD_UID【pbBuffer】指定的CSP上下文无效。

该示例显示了应用程序如何访问特定CSP支持的算法列表。

HCRYPTPROV hProv; //处理CSP

DWORD dwAlgCount;

BYTE *ptr = NULL;

DWORD i;

ALG_ID aiAlgid;

DWORD dwBits;

DWORD dwNameLen;

CHAR szName[100]; //经常被动态分配。

BYTE pbData[1000]; //经常被动态分配。

DWORD dwDataLen;

DWORD dwFlags;

CHAR *pszAlgType = NULL;

//枚举支持的算法。

for(i=0 ; ; i++) {

//通过循环首次设置CRYPT_FIRST标志。

if(i == 0) {

dwFlags = CRYPT_FIRST;

} else {

dwFlags = 0;

}

//检索有关算法的信息。

dwDataLen = 1000;

if(!CryptGetProvParam(hProv,PP_ENUMALGS,pbData,& dwDataLen,0)){

if(GetLastError() == ERROR_NO_MORE_ITEMS) {

//退出循环。

break;

} else {

printf("Error %x reading algorithm!\n", GetLastError());

return;

}

}

//从“pbData”缓冲区中提取算法信息。

ptr = pbData;

aiAlgid = *(ALG_ID *)ptr;

ptr += sizeof(ALG_ID);

dwBits = *(DWORD *)ptr;

ptr += sizeof(DWORD);

dwNameLen = *(DWORD *)ptr;

ptr += sizeof(DWORD);

strncpy(szName, ptr,dwNameLen);

//确定算法类型。

开关(GET_ALG_CLASS(aiAlgid)){

case ALG_CLASS_DATA_ENCRYPT: pszAlgType = "Encrypt ";

break;

case ALG_CLASS_HASH: pszAlgType = "Hash ";

break;

case ALG_CLASS_KEY_EXCHANGE: pszAlgType = "Exchange ";

break;

case ALG_CLASS_SIGNATURE: pszAlgType = "Signature";

break;

default: pszAlgType = "Unknown ";

}

//打印有关算法的信息。

printf(“Algid:%8.8xh,Bits:% - 4d,Type:%s,NameLen:% - 2d,Name:%s \\ n”,

aiAlgid,dwBits,pszAlgType,dwNameLen,szName的

);

}

也可以看看

CryptAcquireContext, CryptCreateHash,CryptDeriveKey, CryptGenKey, CryptGetKeyParam, CryptSetProvParam