CertFindCertificateInStore 函数 (wincrypt.h)

CertFindCertificateInStore 函数在证书存储中查找第一个或下一个证书上下文,该上下文dwFindType 及其关联的 pvFindPara 建立的搜索条件匹配。 此函数可以在循环中用于查找与指定 查找 条件匹配的 证书存储中的所有证书

语法

PCCERT_CONTEXT CertFindCertificateInStore(
  [in] HCERTSTORE     hCertStore,
  [in] DWORD          dwCertEncodingType,
  [in] DWORD          dwFindFlags,
  [in] DWORD          dwFindType,
  [in] const void     *pvFindPara,
  [in] PCCERT_CONTEXT pPrevCertContext
);

参数

[in] hCertStore

要搜索的 证书存储 的句柄。

[in] dwCertEncodingType

指定使用的编码类型。 必须通过将证书和 消息编码类型 与按位 OR 操作组合来指定,如以下示例所示:

X509_ASN_ENCODING |PKCS_7_ASN_ENCODING当前定义的编码类型为:

  • X509_ASN_ENCODING
  • PKCS_7_ASN_ENCODING

[in] dwFindFlags

与某些 dwFindType 值一起使用以修改搜索条件。 对于大多数 dwFindType 值,不使用 dwFindFlags ,应设置为零。 有关详细信息,请参阅备注。

[in] dwFindType

指定要进行的搜索的类型。 搜索类型确定 pvFindPara 的数据类型、内容和用法。 此参数的取值可为下列值之一:

含义
CERT_FIND_ANY
pvFindPara 的数据类型:NULL,未使用。

未使用搜索条件。 返回存储中的下一个证书。

注意 证书上下文的顺序可能不会保留在存储中。 若要访问特定证书,必须循环访问存储中的证书。
 
CERT_FIND_CERT_ID
pvFindPara 的数据类型:CERT_ID结构。

查找由指定 CERT_ID标识的证书。

CERT_FIND_CTL_USAGE
pvFindPara 的数据类型:CTL_USAGE 结构。

搜索具有szOID_ENHANCED_KEY_USAGE扩展的证书或与 CTL_USAGE 结构的 pszUsageIdentifier 成员匹配的 CERT_CTL_PROP_ID

CERT_FIND_ENHKEY_USAGE
pvFindPara 的数据类型:CERT_ENHKEY_USAGE结构。

在存储中搜索具有增强密钥用法扩展或增强密钥用法属性的证书,以及与 CERT_ENHKEY_USAGE 结构中的 cUsageIdentifier 成员匹配的使用标识符。

如果证书具有CERT_EXTENSION结构,并将 pszObjId 成员设置为 szOID_ENHANCED_KEY_USAGE,则证书具有增强的密钥使用扩展。

如果设置了证书CERT_ENHKEY_USAGE_PROP_ID标识符,则证书具有增强的密钥使用属性。

如果在 dwFindFlags 中设置了CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG,则不带密钥用法扩展或属性的证书也会匹配。 设置此标志优先于在 pvFindPara 中传递 NULL

如果设置了CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,则仅对密钥用法扩展执行匹配。

有关对搜索条件的标志修改的信息,请参阅备注。

CERT_FIND_EXISTING
pvFindPara 的数据类型:CERT_CONTEXT 结构。

搜索与指定证书上下文完全匹配的证书。

CERT_FIND_HASH
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

搜索具有与 CRYPT_HASH_BLOB 结构中的哈希匹配的 SHA1 哈希的证书。

CERT_FIND_HAS_PRIVATE_KEY
pvFindPara 的数据类型:NULL,未使用。

搜索具有私钥的证书。 密钥可以是临时的,也可以保存在磁盘上。 密钥可以是旧式加密 API (CAPI) 密钥或 CNG 密钥。

注意 证书上下文的顺序可能不会保留在存储中。 因此,若要访问特定证书,必须循环访问所有证书。
 
Windows 8和Windows Server 2012:开始支持此标志。
CERT_FIND_ISSUER_ATTR
pvFindPara 的数据类型:CERT_RDN结构。

搜索具有与 CERT_RDN 结构中的属性匹配的指定颁发者属性的证书。 如果设置了这些值,该函数会将证书中颁发者的属性与此CERT_RDN结构中的CERT_RDN_ATTR数组的元素进行比较。 比较会循环访问 CERT_RDN_ATTR 属性,查找与证书颁发者属性的匹配项。

如果 CERT_RDN_ATTRpszObjId 成员为 NULL,则忽略属性对象标识符。

如果 CERT_RDN_ATTRdwValueType 成员CERT_RDN_ANY_TYPE,则忽略值类型。

如果 CERT_RDN_VALUE_BLOBpbData 成员为 NULL,则任何值都是匹配项。

目前仅支持精确区分大小写的匹配。 有关 Unicode 选项的信息,请参阅备注。 设置这些值后,搜索仅限于编码类型与 dwCertEncodingType 匹配的证书。

CERT_FIND_ISSUER_NAME
pvFindPara 的数据类型:CERT_NAME_BLOB 结构。

搜索与整个颁发者名称完全匹配的证书,该名称在 CERT_NAME_BLOB 搜索仅限于与 dwCertEncodingType 匹配的证书。

CERT_FIND_ISSUER_OF
pvFindPara 的数据类型:CERT_CONTEXT 结构。

搜索主题与 CERT_CONTEXT 中的颁发者匹配的证书。

使用 CertGetCertificateChain 函数,而不是将 CertFindCertificateInStore 与此值一起使用。

CERT_FIND_ISSUER_STR
pvFindPara 的数据类型:以 Null 结尾的 Unicode 字符串。

搜索包含指定颁发者名称字符串的证书。 证书的颁发者成员使用格式为CERT_SIMPLE_NAME_STR的 CertNameToStr 格式转换为相应类型的名称字符串。 然后执行不区分大小写的子字符串内字符串匹配。 设置此值后,搜索仅限于编码类型与 dwCertEncodingType 匹配的证书。

如果子字符串匹配失败,并且主题包含具有 Punycode 编码字符串的电子邮件 RDN, 则使用 CERT_NAME_STR_ENABLE_PUNYCODE_FLAG 将主题转换为 Unicode 字符串,然后再次执行子字符串匹配。

CERT_FIND_KEY_IDENTIFIER
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

搜索具有与 CRYPT_HASH_BLOB 中的密钥标识符匹配的 CERT_KEY_IDENTIFIER_PROP_ID 属性的证书

CERT_FIND_KEY_SPEC
pvFindPara 的数据类型:包含密钥规范的 DWORD 变量。

搜索具有与 pvFindPara 中的密钥规范匹配的 CERT_KEY_SPEC_PROP_ID 属性的证书。

CERT_FIND_MD5_HASH
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

搜索具有与 CRYPT_HASH_BLOB 中的哈希匹配的 MD5 哈希 证书。

CERT_FIND_PROPERTY
pvFindPara 的数据类型:包含属性标识符的 DWORD 变量。

搜索具有与 pvFindPara 中的 DWORD 值指定的属性标识符匹配的证书。

CERT_FIND_PUBLIC_KEY
pvFindPara 的数据类型:CERT_PUBLIC_KEY_INFO 结构。

搜索具有与 CERT_PUBLIC_KEY_INFO 结构中的公钥匹配的公钥的证书。

CERT_FIND_SHA1_HASH
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

搜索具有与 CRYPT_HASH_BLOB 结构中的哈希匹配的 SHA1 哈希的证书。

CERT_FIND_SIGNATURE_HASH
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

搜索具有与 CRYPT_HASH_BLOB 结构中的签名哈希匹配的签名哈希 证书。

CERT_FIND_SUBJECT_ATTR
pvFindPara 的数据类型:CERT_RDN 结构。

搜索具有与 CERT_RDN 结构中的属性匹配的指定使用者属性 证书。 如果设置了 RDN 值,该函数会将证书中使用者的属性与此CERT_RDN结构中的 CERT_RDN_ATTR 数组的元素进行比较。 比较将循环访问 CERT_RDN_ATTR 属性,以查找与证书使用者属性的匹配项。

如果 CERT_RDN_ATTRpszObjId 成员为 NULL,则忽略属性对象标识符。

如果 CERT_RDN_ATTRdwValueType 成员CERT_RDN_ANY_TYPE,则忽略值类型。

如果 CERT_RDN_VALUE_BLOBpbData 成员为 NULL,则任何值都是匹配项。

目前仅支持完全区分大小写的匹配项。

有关 Unicode 选项的信息,请参阅备注。 设置这些值后,搜索仅限于编码类型与 dwCertEncodingType 匹配的证书。

CERT_FIND_SUBJECT_CERT
pvFindPara 的数据类型:CERT_INFO结构。

CERT_INFO 结构中,搜索证书的颁发者和序列号与颁发者和序列号匹配。

CERT_FIND_SUBJECT_NAME
pvFindPara 的数据类型:CERT_NAME_BLOB 结构。

搜索证书,该证书与整个使用者名称与 CERT_NAME_BLOB 结构中的名称完全匹配。 搜索仅限于与 dwCertEncodingType 的值匹配的证书。

CERT_FIND_SUBJECT_STR
pvFindPara 的数据类型:以 Null 结尾的 Unicode 字符串。

搜索包含指定使用者名称字符串的证书。 证书的使用者成员将使用格式为 CERT_SIMPLE_NAME_STR 的 CertNameToStr 格式转换为相应类型的名称字符串。 然后执行不区分大小写的子字符串内字符串匹配。 设置此值后,搜索仅限于编码类型与 dwCertEncodingType 匹配的证书。

CERT_FIND_CROSS_CERT_DIST_POINTS
pvFindPara 的数据类型:未使用。

查找具有跨证书分发点扩展或属性的证书。

CERT_FIND_PUBKEY_MD5_HASH
pvFindPara 的数据类型:CRYPT_HASH_BLOB结构。

查找其 MD5 哈希公钥与指定哈希匹配的证书。

 
注意dwFindType 值的替代形式在 pvFindPara 中传递字符串。 一个窗体使用 Unicode 字符串,另一个窗体使用 ASCII 字符串。 以“_W”结尾或不带后缀的值使用 Unicode。 以“_A”结尾的值使用 ASCII 字符串。
 

[in] pvFindPara

指向与 dwFindType 一起使用的数据项或结构。

[in] pPrevCertContext

指向此函数返回的最后 一个CERT_CONTEXT 结构的指针。 首次调用函数时,此参数必须为 NULL 。 若要查找符合搜索条件的连续证书,请将 pPrevCertContext 设置为上一次调用函数返回的指针。 此函数释放此参数的非 NULL 值引用的CERT_CONTEXT

返回值

如果函数成功,该函数将返回指向只读 CERT_CONTEXT 结构的指针。

如果函数失败,并且找不到与搜索条件匹配的证书,则返回值为 NULL

CertFindCertificateInStore 返回的非 NULLCERT_CONTEXT必须由 CertFreeCertificateContext 释放,或者在后续调用 CertFindCertificateInStore 时作为 pPrevCertContext 参数传递。

有关扩展的错误信息,请调用 GetLastError。 下面是一些可能的错误代码。

返回代码 说明
CRYPT_E_NOT_FOUND
找不到与搜索条件匹配的证书。 如果存储为空或到达存储区列表的末尾,则可能会发生这种情况。
E_INVALIDARG
hCertStore 参数中的句柄与 pPrevCertContext 参数指向的证书上下文中的句柄不同,或者在 dwFindType 参数中指定了无效的值。

注解

dwFindFlags 参数用于修改某些搜索类型的条件。

CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags 值仅用于 dwFindType 的CERT_FIND_SUBJECT_ATTR和CERT_FIND_ISSUER_ATTR值。 如果 pvFindPara 指向的 CERT_RDN_ATTR 结构是使用 Unicode 字符串初始化的,则必须设置CERT_UNICODE_IS_RDN_ATTRS_FLAG。 在进行任何比较之前,将使用 X509_UNICODE_NAME 转换要匹配的字符串,以便为 Unicode 比较提供 。

以下 dwFindFlags 值仅用于 dwFindType 的 CERT_FIND_ENKEY_USAGE 值:

可以调用 CertDuplicateCertificateContext 来复制返回的上下文。 可以使用 CertAddCertificateContextToStore 将返回的上下文添加到不同的证书存储区,也可以使用 CertAddCertificateLinkToStore 将指向该证书上下文的链接添加到不是集合存储的存储。

在对函数的后续调用中作为 pPrevCertContext 参数传递时,返回的指针将被释放。 否则,必须通过调用 CertFreeCertificateContext 显式释放指针。 CertFindCertificateInStore 始终使用调用 CertFreeCertificateContext 释放不为 NULLpPrevCertContext,即使函数中存在错误也是如此。

示例

以下示例演示如何在符合搜索条件的证书存储中查找证书上下文。 有关包含此示例上下文的完整示例,请参阅 示例 C 程序:证书存储操作

有关使用此函数的另一个示例,请参阅 示例 C 程序:集合和同级证书存储操作

#include <windows.h>
#include <stdio.h>
#include <Wincrypt.h>
#pragma comment(lib, "crypt32.lib")

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void main()
{
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE  hSystemStore;              // The system store handle.
PCCERT_CONTEXT  pDesiredCert = NULL;   // Set to NULL for the first 
                                       // call to
                                       // CertFindCertificateInStore.
LPCSTR lpszCertSubject = (LPCSTR) "Cert_subject_1";


//-------------------------------------------------------------------
// Open the certificate store to be searched.

if(hSystemStore = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, 
     0,                      // Encoding type not needed 
                             // with this PROV.
     NULL,                   // Accept the default HCRYPTPROV. 
     CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the system store location in 
                             // the registry.
     L"MY"))                 // Could have used other predefined 
                             // system stores
                             // including Trust, CA, or Root.
{
   printf("Opened the MY system store. \n");
}
else
{
   printf( "Could not open the MY system store.\n");
   exit(1);
}
//-------------------------------------------------------------------
// Get a certificate that has lpszCertSubject as its 
// subject. 

if(pDesiredCert=CertFindCertificateInStore(
      hSystemStore,
      MY_ENCODING_TYPE,           // Use X509_ASN_ENCODING.
      0,                          // No dwFlags needed. 
      CERT_FIND_SUBJECT_STR,      // Find a certificate with a
                                  // subject that matches the string
                                  // in the next parameter.
      lpszCertSubject ,           // The Unicode string to be found
                                  // in a certificate's subject.
      NULL))                      // NULL for the first call to the
                                  // function. In all subsequent
                                  // calls, it is the last pointer
                                  // returned by the function.
{
  printf("The desired certificate was found. \n");
}
else
{
   printf("Could not find the desired certificate.\n");
}
//-------------------------------------------------------------------
// Clean up. 

if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(hSystemStore)
    CertCloseStore(
        hSystemStore, 
        CERT_CLOSE_STORE_CHECK_FLAG);

要求

要求
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 wincrypt.h
Library Crypt32.lib
DLL Crypt32.dll

另请参阅

CERT_CONTEXT

CertAddCertificateContextToStore

CertAddCertificateLinkToStore

CertDuplicateCertificateContext

CertEnumCertificatesInStore

CertFreeCertificateContext

CertGetCertificateChain

CertNameToStr

证书函数