[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这是传递给CryptGenKey,CryptDeriveKey或CryptCreateHash 函数的值,以便指定使用特定的算法。 |
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_MD2 | ALG_CLASS_HASH |
"MD5" | CALG_MD5 | ALG_CLASS_HASH |
"SHA" | CALG_SHA | ALG_CLASS_HASH |
"MAC" | CALG_MAC | ALG_CLASS_HASH |
"RSA_SIGN" | CALG_RSA_SIGN | ALG_CLASS_SIGNATURE |
"RSA_KEYX" | CALG_RSA_KEYX | ALG_CLASS_KEY_EXCHANGE |
"RC2" | CALG_RC2 | ALG_CLASS_DATA_ENCRYPT |
"RC4" | CALG_RC4 | ALG_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