CertOpenStore 函数 (wincrypt.h)
CertOpenStore 函数使用指定的存储提供程序类型打开 证书存储。 虽然此函数可以打开证书存储,但建议 CertOpenSystemStore 打开最常见的证书存储。 CertOpenStore 对于更复杂的选项和特殊情况是必需的。
语法
HCERTSTORE CertOpenStore(
[in] LPCSTR lpszStoreProvider,
[in] DWORD dwEncodingType,
[in] HCRYPTPROV_LEGACY hCryptProv,
[in] DWORD dwFlags,
[in] const void *pvPara
);
参数
[in] lpszStoreProvider
指向包含存储提供程序类型的以 null 结尾的 ANSI 字符串的指针。
以下值表示预定义的存储类型。 存储提供程序类型确定 pvPara 参数的内容以及 dwFlags 参数的高字的使用和含义。 可以使用 CryptInstallOIDFunctionAddress 或 CryptRegisterOIDFunction 函数安装或注册其他存储提供程序。 有关添加存储提供程序的详细信息,请参阅 扩展 CertOpenStore 功能。
价值 | 意义 |
---|---|
|
打开一个存储区,该存储将是其他存储的集合。 存储通过使用 CertAddStoreToCollection 和 CertRemoveStoreFromCollection添加到集合或从集合中删除。 将存储添加到集合中时,该存储中的所有证书、CRL 和 CCL 都可用于搜索或枚举集合存储。
dwFlags 的高字设置为零。 pvPara 值:pvPara 参数必须 NULL。 |
|
使用从指定的打开文件中读取的证书、CRL 和 CCL 初始化存储区。 此提供程序要求该文件仅包含序列化存储,而不是 PKCS #7 签名消息或单个编码证书。
文件指针必须位于序列化存储信息的开头。 将序列化存储中的数据加载到证书存储中后,文件指针将定位在可跟踪序列化存储数据的任何数据的开头。 如果在 dwFlags中设置CERT_FILE_STORE_COMMIT_ENABLE,则文件句柄将重复,并且存储始终作为序列化存储提交。 当存储关闭时,该文件不会关闭。 pvPara 值:pvPara 参数必须包含指向 使用 createFile打开的文件句柄的指针。 |
|
使用文件中的证书、CRL 和 CCL 初始化存储区。 提供程序打开该文件,并首先尝试将文件读取为序列化存储,然后作为 PKCS #7 签名消息,最后作为单个编码的证书。
dwEncodingType 参数必须包含用于消息和证书的编码类型。 如果文件包含 X.509 编码证书,则打开操作将失败,并且调用 GetLastError 函数将返回 ERROR_ACCESS_DENIED。
如果在 dwFlags
如果 dwFlags 包括 CERT_FILE_STORE_COMMIT_ENABLE,该文件将作为 PKCS #7 或序列化存储提交,具体取决于打开的文件类型。 如果文件为空,或者文件名具有 .p7c 或 .spc 扩展名,则该文件将提交为 PKCS #7。 否则,该文件将作为序列化存储提交。 pvPara 值:pvPara 参数必须包含指向以 null 结尾的 ANSI 字符串的指针,该字符串包含现有未打开的文件的名称。 |
|
与 CERT_STORE_PROV_FILENAME_A相同。
pvPara 值:pvPara 参数必须包含指向 null 终止的 Unicode 字符串的指针,该字符串包含现有未打开的文件的名称。 |
|
使用 LDAP 查询结果中的证书、CRL 和 CCL 初始化存储区。
若要对存储执行写入操作,查询字符串必须指定没有筛选器和单个属性的 BASE 查询。 pvPara 值:如果 dwFlags 参数包含 CERT_LDAP_STORE_OPENED_FLAG,请将 pvPara 设置为指定要使用的已建立 LDAP 会话的 CERT_LDAP_STORE_OPENED_PARA 结构的地址。 否则,请将 pvPara 设置为指向包含 LDAP 查询字符串的以 null 结尾的 Unicode 字符串。 有关 LDAP 查询字符串的详细信息,请参阅 LDAP 方言。 |
|
在缓存内存中创建证书存储。
证书吊销列表(CRL)或 证书信任列表(CCL)最初加载到存储区中。 通常用于创建临时存储。
不会自动保存内存存储中证书、CRL 或 CCL 的属性中的任何证书、CRL 或 CCL 或更改。 可以使用 CertSaveStore将其保存到文件或内存 BLOB。 pvPara 值:不使用 pvPara 参数。 |
|
使用指定的加密消息中的证书、CRL 和 CCL 初始化存储。
dwEncodingType 参数必须包含用于消息和证书的编码类型。
pvPara 值:pvPara 参数包含编码消息的 HCRYPTMSG 句柄,由调用 CryptMsgOpenToDecode返回。 |
|
使用证书、CRL 和 CCL 从作为逻辑系统存储成员的指定物理存储区初始化存储。
两个名称用干预反斜杠(\)分隔,例如“Root.Default”。 此处,“Root”是系统存储和“的名称。默认值为物理存储的名称。 系统和物理存储名称不能包含任何反斜杠。 dwFlags 的高字表示系统存储位置,通常CERT_SYSTEM_STORE_CURRENT_USER。 有关详细信息,请参阅本主题后面的 dwFlags,并参阅 系统存储位置。 某些物理存储位置可以远程打开。 pvPara 值:pvPara 参数指向包含系统存储名称和物理名称的以 null 结尾的 Unicode 字符串。 |
|
使用编码的 PKCS #7 签名消息中的证书、CRL 和 CCL 初始化存储。
dwEncodingType 参数必须指定要用于消息和证书的编码类型。
pvPara 值:pvPara 参数指向表示编码消息的 CRYPT_DATA_BLOB 结构。 |
|
使用 PKCS #12 数据包的内容初始化存储。
如果 PKCS #12 数据包使用 NULL 或空密码进行保护,则此函数将成功打开存储区。 从 Windows 8 和 Windows Server 2012 开始,如果 PFX 数据包中嵌入的密码受到 Active Directory (AD) 主体的保护,并且当前用户作为该主体的成员有权解密密码,此函数将成功打开存储区。 有关详细信息,请参阅 pvPara 参数和 PFXExportCertStoreEx 函数的 PKCS12_PROTECT_TO_DOMAIN_SIDS 标志。 可以从 Windows 8 和 Windows Server 2012 开始保护 AD 主体的 PFX 密码。 pvPara 值:pvPara 参数指向表示 PKCS #12 数据包的 CRYPT_DATA_BLOB 结构。 |
|
使用注册表子项中的证书、CRL 和 CCL 初始化存储区。
此提供程序打开或创建注册表子项 证书、CRL,并在传入 pvPara的密钥下 CCL。 提供程序不会关闭输入键。 在返回之前,提供程序将打开传入 pvPara的密钥副本。 如果CERT_STORE_READONLY_FLAG在 dwFlags的低单词中设置,则注册表子项将使用具有 KEY_READ_ACCESS 的 RegOpenKey 打开。 否则,注册表子项是使用 RegCreateKey 和KEY_ALL_ACCESS创建的。 对打开的存储区内容所做的任何更改都会立即保存到注册表中。 但是,如果CERT_STORE_READONLY_FLAG是在 dwFlags的低字中设置的,则任何尝试添加到存储区的内容或更改上下文的属性将导致 GetLastError 返回E_ACCESSDENIED代码时出错。 pvPara 值:pvPara 参数包含打开的注册表项的句柄。 |
|
使用包含序列化存储的内存位置的证书、CRL 和 CCL 初始化存储区。
pvPara 值:pvPara 参数指向包含序列化内存 BLOB 的 CRYPT_DATA_BLOB 结构。 |
|
当前未使用。 |
|
使用指定系统存储中的证书、CRL 和 CCL 初始化存储区。
系统存储是一个逻辑集合存储,由一个或多个物理存储组成。 与系统存储关联的物理存储向 CertRegisterPhysicalStore 函数注册。 打开系统存储后,与它关联的所有物理存储也通过调用 CertOpenStore 打开,并使用 CertAddStoreToCollection 函数添加到系统存储集合中。 dwFlags 的高字 表示系统存储位置,通常设置为CERT_SYSTEM_STORE_CURRENT_USER。 有关注册表位置的详细信息,请参阅本主题后面的 dwFlags,系统存储位置。 某些系统存储位置可以远程打开;有关详细信息,请参阅系统存储位置。 pvPara 值:pvPara 参数指向包含系统存储名称(如“My”或“Root”)的以 null 结尾的 ANSI 字符串。 |
|
与 CERT_STORE_PROV_SYSTEM_A相同。
pvPara 值:pvPara 参数指向包含系统存储名称(如“My”或“Root”)的以 null 结尾的 Unicode 字符串。 |
|
使用物理注册表存储中的证书、CRL 和 CCL 初始化存储区。 物理存储未作为集合存储打开。 枚举和搜索仅经历该物理存储中的证书、CRL 和 CCL。
dwFlags 的高字 表示系统存储位置,通常设置为CERT_SYSTEM_STORE_CURRENT_USER。 有关详细信息,请参阅本主题后面的 dwFlags。 某些系统存储位置可以远程打开;有关详细信息,请参阅 系统存储位置。 pvPara 值:pvPara 参数指向包含系统存储名称(如“My”或“Root”)的以 null 结尾的 ANSI 字符串。 |
|
与 CERT_STORE_PROV_SYSTEM_REGISTRY_A相同。
pvPara 值:pvPara 参数指向包含系统存储名称(如“My”或“Root”)的以 null 结尾的 Unicode 字符串。 |
[in] dwEncodingType
指定 证书编码类型 和 消息编码类型。 仅当 CertSaveStore 函数包含 CERT_STORE_SAVE_AS_PKCS7的 dwSaveAs 参数时,才使用编码。 否则,不使用 dwMsgAndCertEncodingType 参数。
此参数仅适用于在 lpszStoreProvider 参数中指定的 CERT_STORE_PROV_MSG、CERT_STORE_PROV_PKCS7或 CERT_STORE_PROV_FILENAME 提供程序类型。 对于所有其他提供程序类型,此参数未使用,应设置为零。
此参数可以是以下一个或多个值的组合。
价值 | 意义 |
---|---|
|
指定 PKCS #7 消息编码。 |
|
指定 X.509 证书编码。 |
[in] hCryptProv
此参数未使用,应设置为 NULL。
Windows Server 2003 和 Windows XP:加密提供程序的句柄。 为此参数传递 NULL 会导致使用适当的默认提供程序。 建议使用默认提供程序。 默认或指定的加密提供程序用于验证使用者证书或 CRL 签名的所有存储函数。此参数的数据类型 HCRYPTPROV。
[in] dwFlags
这些值由使用按位OR 运算组合的高字值和低字值组成。
dwFlags 的低字部分 控制打开 证书存储 的各种常规特征。 此部分可用于所有存储提供程序类型。 dwFlags 的低字部分可以是以下值之一。
价值 | 意义 |
---|---|
|
使用线程的SE_BACKUP_NAME和SE_RESTORE_NAME 权限 打开注册表或基于文件的系统存储。 如果线程没有这些权限,则此函数必须失败,并出现访问被拒绝错误。 |
|
如果不存在新存储,则会创建一个新存储。 如果存储已存在,该函数将失败。
如果 CERT_STORE_OPEN_EXISTING_FLAG 和 CERT_STORE_CREATE_NEW_FLAG 均未设置,则存储区存在或创建并打开(如果尚不存在)。 |
|
延迟关闭存储提供程序,直到存储中获取的所有证书、CRL 或 CCL 不再使用。 当从存储中获取的最后一个证书、CRL 或 CTL 释放时,实际上会关闭存储区。 即使调用 CertCloseStore,对这些证书、CRL 和 CCL 的属性所做的任何更改也会保留。
如果未设置此标志,并且存储中获取的证书、CRL 或 CCL 仍在使用中,则不会保留对这些证书、CRL 和 CCL 的属性的任何更改。 如果使用 CERT_CLOSE_STORE_FORCE_FLAG调用此函数,则忽略 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG。 设置此标志并传递非NULLhCryptProv 参数值时,即使调用此函数后,该提供程序仍将继续使用该提供程序。 |
|
存储区被删除,而不是被打开。 对于删除成功和失败,此函数返回 NULL。 若要确定删除的成功,请调用 GetLastError,如果删除存储,则返回零;如果未删除,则返回非零值。 |
|
通常,存储区中所有证书的枚举将忽略 CERT_ARCHIVED_PROP_ID 属性集的任何证书。 如果设置了此标志,则存储区中证书的枚举将包含存储中的所有证书,包括具有 CERT_ARCHIVED_PROP_ID 属性的证书。 |
|
打开具有最大允许权限集的存储区。 如果指定了此标志,则首先使用写入访问权限打开注册表存储,如果失败,则会使用只读访问权限重新打开它们。 |
|
当 hCryptProv 参数 NULL时,不使用此标志。 仅当非NULL CSP 句柄作为 hCryptProv 参数传递时,此标志才有效。 设置此标志可防止关闭证书存储时自动释放非默认 CSP。 |
|
仅打开现有存储区。 如果存储不存在,函数将失败。 |
|
以只读模式打开存储区。 任何更改存储内容尝试都将导致错误。 设置此标志并使用基于注册表的存储提供程序时,将使用 KEY_READ_ACCESSRegOpenKey 打开注册表子项。 否则,注册表子项是使用 KEY_ALL_ACCESSRegCreateKey 创建的。 |
|
如果支持此标志,提供程序将设置存储 CERT_STORE_LOCALIZED_NAME_PROP_ID 属性。 可以通过调用 CertGetStoreProperty 函数(dwPropID 设置为 CERT_STORE_LOCALIZED_NAME_PROP_ID)来检索本地化名称。 CERT_STORE_PROV_FILENAME、CERT_STORE_PROV_SYSTEM、CERT_STORE_PROV_SYSTEM_REGISTRY和 CERT_STORE_PROV_PHYSICAL_W类型的提供程序支持此标志。 |
|
多次打开存储时,可以设置此标志,通过跨存储打开的实例重用证书、CRL 或 CTL 上下文的编码部分的内存,确保内存使用率高效。 |
|
CurrentUser 和 LocalMachine 中存在密钥标识符的列表。 这些密钥标识符的属性与证书的属性非常类似。 如果设置了 CERT_STORE_UPDATE_KEYID_FLAG,则对于存储区中具有 CERT_KEY_PROV_INFO_PROP_ID 属性的每个密钥标识符,该属性将从密钥标识符属性 CERT_KEY_PROV_INFO_PROP_ID 或与该密钥标识符相关的证书 CERT_KEY_IDENTIFIER_PROP_ID 自动更新。 |
CERT_STORE_PROV_SYSTEM、CERT_STORE_PROV_SYSTEM_REGISTRY和 CERT_STORE_PROV_PHYSICAL 提供程序类型使用以下高字 dwFlags 来指定系统存储注册表位置:
CERT_SYSTEM_STORE_CURRENT_SERVICE
CERT_SYSTEM_STORE_CURRENT_USER
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
CERT_SYSTEM_STORE_LOCAL_MACHINE
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
CERT_SYSTEM_STORE_SERVICES
CERT_SYSTEM_STORE_USERS
默认情况下,系统存储位置相对于 HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE或 HKEY_USERS 预定义的注册表项打开。 有关详细信息,请参阅 系统存储位置。
以下高字标志将替代此默认行为。
价值 | 意义 |
---|---|
|
设置时,pvPara 必须包含指向 CERT_SYSTEM_STORE_RELOCATE_PARA 结构的指针,而不是字符串。 该结构指示存储的名称及其在注册表中的位置。 |
|
默认情况下,当 CurrentUser“Root”存储打开时,此函数返回之前,不在受保护根列表上的 SystemRegistry 根列表的任何 SystemRegistry 根将从缓存中删除。 设置此标志时,将重写此默认值,并返回 SystemRegistry 中的所有根,并且不会检查受保护的根列表。 |
CERT_STORE_PROV_REGISTRY 提供程序使用以下高字标志。
价值 | 意义 |
---|---|
|
pvPara 包含远程计算机上的注册表项句柄。 若要访问远程计算机上的注册表项,必须将远程计算机上的安全权限设置为允许访问。 有关详细信息,请参阅“备注”。 |
|
CERT_STORE_PROV_REG 提供程序将证书、CRL 和 CCL 保存在单个序列化存储子项中,而不是执行默认保存操作。 默认值是,每个证书、CRL 或 CTL 都保存为相应的子项下的单独注册表子项。
此标志主要用于从组策略模板(GPT)下载的存储,例如 CurrentUserGroupPolicy 和 LocalMachineGroupPolicy 存储。 设置 CERT_REGISTRY_STORE_SERIALIZED_FLAG 时,在调用 CertCloseStore 或使用 CERT_STORE_CTRL_COMMITCertControlStore 之前,不会保留存储添加、删除或属性更改。 |
CERT_STORE_PROV_FILE 和 CERT_STORE_PROV_FILENAME 提供程序类型使用以下高单词标志。
CERT_STORE_PROV_LDAP 提供程序类型使用以下高字标志。
价值 | 意义 |
---|---|
|
对 pvPara 参数中命名的 URL 执行仅限 A 记录的 DNS 查找。 这可以防止解析 URL 主机名时生成错误的 DNS 查询。 在传递主机名而不是 pvPara 参数的域名时使用此标志。 |
|
使用此标志来使用现有的 LDAP 会话。 指定此标志时,pvPara 参数是包含要使用的 LDAP 会话信息的 CERT_LDAP_STORE_OPENED_PARA 结构的地址。 |
|
若要提供某些应用程序所需的完整性,请使用 Kerberos 身份验证协议对 LDAP 服务器的所有 LDAP 流量进行数字签名。 |
|
将此标志与 CERT_LDAP_STORE_OPENED_FLAG 标志一起使用,导致存储关闭时 LDAP 会话未绑定。 关闭存储时,系统会使用 ldap_unbind 函数取消绑定 LDAP 会话。 |
[in] pvPara
一个 32 位值,可以包含此函数的其他信息。 此参数的内容取决于 lpszStoreProvider 和其他参数的值。
返回值
如果函数成功,该函数将返回 证书存储句柄。 使用完存储后,通过调用 CertCloseStore 函数释放句柄。
如果函数失败,它将返回 NULL 。 有关扩展错误信息,请调用 GetLastError。
言论
系统存储是一个集合,由一个或多个物理同级存储组成。 对于每个系统存储,都有预定义的物理同级存储。 在CERT_SYSTEM_STORE_CURRENT_USER打开系统存储(如“My”)后,将调用 CertOpenStore 以打开系统存储集合中的所有物理存储。 其中每个物理存储都通过使用 CertAddStoreToCollection 函数添加到系统存储集合中。 这些物理存储中的所有证书、CRL 和 CCL 都可通过逻辑系统存储集合获得。
可以远程打开以下系统存储位置:
- CERT_SYSTEM_STORE_LOCAL_MACHINE
- CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
- CERT_SYSTEM_STORE_SERVICES
- CERT_SYSTEM_STORE_USERS
系统存储位置通过在传递给 pvPara 的字符串中加上计算机名称的前缀来远程打开系统存储位置。 远程系统存储名称的示例包括:
- ComputerName\CA
- \\ComputerName\CA
- ComputerName\ServiceName\Trust
- \\ComputerName\ServiceName\Trust
有关系统存储的详细信息,请参阅 系统存储位置。
有关自动迁移的存储的详细信息,请参阅 证书存储迁移。
例子
以下示例演示如何打开不同存储提供程序类型的多个证书存储。 该示例使用 CreateMyDACL 函数(在 创建 DACL 主题中定义)来确保使用正确的 DACL 创建打开的文件。 有关打开其他存储提供程序类型的更多示例,请参阅 用于打开证书存储的示例 C 代码。
//-------------------------------------------------------------------
// Open a system store, in this case, the My store.
HCERTSTORE hSysStore = NULL;
if(hSysStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // The store provider type
0, // The encoding type is
// not needed
NULL, // Use the default HCRYPTPROV
CERT_SYSTEM_STORE_CURRENT_USER, // Set the store location in a
// registry location
L"MY" // The store name as a Unicode
// string
))
{
printf("The system store was created successfully.\n");
}
else
{
printf("An error occurred during creation "
"of the system store!\n");
exit(1);
}
// Other common system stores include "Root", "Trust", and "Ca".
//-------------------------------------------------------------------
// Open a memory store.
HCERTSTORE hMemStore = NULL;
if(hMemStore = CertOpenStore(
CERT_STORE_PROV_MEMORY, // The memory provider type
0, // The encoding type is not needed
NULL, // Use the default HCRYPTPROV
0, // Accept the default dwFlags
NULL // pvPara is not used
))
{
printf("The memory store was created successfully.\n");
}
else
{
printf("An error occurred during creation "
"of the memory store!\n");
exit(1);
}
//-------------------------------------------------------------------
// Open a read-only store from disk.
HANDLE hFile = NULL;
HCERTSTORE hFileStore = NULL;
LPCSTR pszFileName = "TestStor2.sto";
SECURITY_ATTRIBUTES sa; // For DACL
// Create a DACL to use when opening the file.
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
// Call function to set the DACL. The DACL is set in the
// SECURITY_ATTRIBUTES lpSecurityDescriptor member.
if (!CreateMyDACL(&sa))
{
// Error encountered; generate message and exit.
printf("Failed CreateMyDACL.\n");
exit(1);
}
// Obtain the file handle of an existing file.
if (hFile = CreateFile(
pszFileName, // The file name
GENERIC_READ|GENERIC_WRITE, // Access mode: Read from and
// write to this file
0, // Share mode
&sa, // Uses the DACL created
// previously
OPEN_ALWAYS, // How to create
FILE_ATTRIBUTE_NORMAL, // File attributes
NULL)) // Template
{
printf("The file was opened successfully.\n");
}
else
{
printf("An error occurred during opening of the file!\n");
exit(1);
}
//-------------------------------------------------------------------
// This file can contain data before the store itself.
// At this point, read and use data in the open file that precedes
// the serialized certificate store data.
// To open the certificate store, the file pointer must
// be placed at the beginning of the certificate store data.
//-------------------------------------------------------------------
// Open the store.
if(hFileStore = CertOpenStore(
CERT_STORE_PROV_FILE, // Load certificates from a file
0, // Encoding type not used
NULL, // Use the default HCRYPTPROV
CERT_STORE_READONLY_FLAG, // Read-only store
hFile // The handle for the open file
// that is the source of the
// certificates
))
{
printf("The file store was created successfully.\n");
}
else
{
printf("An error occurred during creation of the file store!\n");
exit(1);
}
//-------------------------------------------------------------------
// After processing, close the certificate stores and the file.
if(CertCloseStore(
hSysStore,
CERT_CLOSE_STORE_CHECK_FLAG))
{
printf("The system store was closed successfully.\n");
}
else
{
printf("An error occurred during closing of the "
"system store.\n");
}
if(CertCloseStore(
hMemStore,
CERT_CLOSE_STORE_CHECK_FLAG))
{
printf("The memory store was closed successfully.\n");
}
else
{
printf("An error occurred during closing of the "
"memory store.\n");
}
if(CertCloseStore(
hFileStore,
CERT_CLOSE_STORE_CHECK_FLAG))
{
printf("The file store was closed successfully.\n");
}
else
{
printf("An error occurred during closing of the file store.\n");
}
if(CloseHandle(hFile))
{
printf("The file was closed successfully.\n");
}
else
{
printf("An error occurred during closing of the file.\n");
}
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [桌面应用 |UWP 应用] |
支持的最低服务器 | Windows Server 2003 [桌面应用 |UWP 应用] |
目标平台 | 窗户 |
标头 | wincrypt.h |
库 | Crypt32.lib |
DLL | Crypt32.dll |