PFXImportCertStore 函数 (wincrypt.h)

PFXImportCertStore 函数导入 PFX BLOB 并返回包含证书和任何关联私钥的存储的句柄。

语法

HCERTSTORE PFXImportCertStore(
  [in] CRYPT_DATA_BLOB *pPFX,
  [in] LPCWSTR         szPassword,
  [in] DWORD           dwFlags
);

参数

[in] pPFX

指向 CRYPT_DATA_BLOB 结构的指针,该结构包含具有导出和加密证书和密钥的 PFX 数据包。

[in] szPassword

用于解密和验证 PFX 数据包的字符串密码。 无论是设置为长度大于零的字符串,还是设置为空字符串或 NULL,此值都必须与用于加密数据包的值完全相同。

从 Windows 8 和 Windows Server 2012 开始,如果 PFX 数据包是使用 PKCS12_PROTECT_TO_DOMAIN_SIDS 标志在 PFXExportCertStoreEx 函数中创建的,则 PFXImportCertStore 函数会尝试使用用于加密它的 Active Directory (AD) 主体来解密密码。 AD 主体在 pvPara 参数中指定。 如果 PFXExportCertStoreEx 函数中的 szPassword 参数为空字符串或 NULL,并且 dwFlags 参数设置为 PKCS12_PROTECT_TO_DOMAIN_SIDS,则该函数会随机生成密码并将其加密到 pvPara 参数中指定的 AD 主体。 在这种情况下,应将密码设置为创建 PFX 数据包时使用的值,即空字符串或 NULLPFXImportCertStore 函数将使用 AD 主体解密随机密码,而随机生成的密码将用于解密 PFX 证书。

使用完密码后,通过调用 SecureZeroMemory 函数将其从内存中清除。 有关保护密码的详细信息,请参阅 处理密码

[in] dwFlags

dwFlags 参数可以是以下值之一:

含义
CRYPT_EXPORTABLE
0x00000001
导入的密钥将标记为可导出。 如果未使用此标志,则调用具有密钥句柄的 CryptExportKey 函数会失败。
CRYPT_USER_PROTECTED
0x00000002
当尝试使用此密钥时,将通过对话框或其他方法通知用户。 精确行为由 加密服务提供程序 指定, (使用的 CSP) 。

在 Internet Explorer 4.0 之前,Microsoft 加密服务提供程序忽略了此标志。 从 Internet Explorer 4.0 开始,Microsoft 提供商支持此标志。

如果打开提供程序上下文时设置了CRYPT_SILENT标志,则使用此标志会导致失败,并且最后一个错误设置为NTE_SILENT_CONTEXT。

CRYPT_MACHINE_KEYSET
0x00000020
私钥存储在本地计算机下,而不是存储在当前用户下。
CRYPT_USER_KEYSET
0x00001000
私钥存储在当前用户下,而不是存储在本地计算机下,即使 PFX BLOB 指定它们应进入本地计算机也是如此。
PKCS12_PREFER_CNG_KSP
0x00000100
指示首选 CNG 密钥存储提供程序 (KSP) 。 如果在 PFX 文件中指定了 CSP,则使用 CSP,否则首选 KSP。 如果 CNG KSP 不可用, PFXImportCertStore 函数将失败。

Windows Server 2003 和 Windows XP: 不支持此值。

PKCS12_ALWAYS_CNG_KSP
0x00000200
指示始终使用 CNG KSP。 指定后, PFXImportCertStore 将尝试使用 CNG KSP,而不考虑 PFX 文件中的提供程序信息。 如果 CNG KSP 不可用,则导入不会失败。

Windows Server 2003 和 Windows XP: 不支持此值。

PKCS12_ALLOW_OVERWRITE_KEY
0x00004000
允许覆盖现有密钥。 如果遇到必须导入包含已存在的密钥名称的 PFX 文件的情况,请指定此标志。 例如,导入 PFX 文件时,可能已存在同名容器,因为密钥容器没有唯一的命名空间。 如果在计算机上创建了“TestKey”,然后导入的 PFX 文件也以“TestKey”作为密钥容器,则 PKCS12_ALLOW_OVERWRITE_KEY 设置允许覆盖密钥。

Windows Server 2003 和 Windows XP: 不支持此值。

PKCS12_NO_PERSIST_KEY
0x00008000
不要保留密钥。 如果不想保留密钥,请指定此标志。 例如,如果验证后不需要存储密钥,则可以指定此标志来立即释放密钥,而不是创建容器并删除它。
注意 如果 PKCS12_NO_PERSIST_KEY 标志未设置,则密钥将保留在磁盘上。 如果不想在密钥的使用之外保留密钥,则必须使用 dwFlags 参数中设置的 CRYPT_DELETEKEYSET 标志调用 CryptAcquireContext 函数来删除它们。
注意 其他一些注意事项:
  • 使用 PKCS12_NO_PERSIST_KEY 时,属性CERT_KEY_CONTEXT_PROP_ID在证书上内部设置,CERT_KEY_CONTEXT_PROP_ID包含NCRYPT_KEY_HANDLE。

  • 如果未使用PKCS12_NO_PERSIST_KEY,则设置 CERT_KEY_PROV_INFO_PROP_ID 属性。

  • 如果将具有非持久密钥的证书封送到另一个进程,则不会封送CERT_KEY_CONTEXT_PROP_ID属性。

  • 要使NO_PERSIST正常工作,它必须处于同一进程中, 并且 PCCERT_CONTEXT的用户必须支持CERT_KEY_CONTEXT_PROP_ID。 这通常在 TLS 握手期间适用:如果在 LSASS.exe 中的调用进程外部执行握手,则从调用进程移动到 LSASS (时,无法使用 PKCS12_NO_PERSIST_KEY,因为NCRYPT_KEY_HANDLE是指向数据结构的指针,而不是内核句柄) 。

 
Windows Server 2003 和 Windows XP: 不支持此值。
PKCS12_INCLUDE_EXTENDED_PROPERTIES
0x0010
导入导出证书时在证书上保存的所有扩展属性。

Windows Server 2003 和 Windows XP: 不支持此值。

0x10000000
解压缩,但不保留结果。

返回值

如果函数成功,该函数将返回包含导入证书(包括可用私钥)的证书存储的句柄。

如果函数失败,即如果 password 参数不包含与用于加密导出数据包的密码完全匹配,或者如果解码 PFX BLOB 时存在任何其他问题,则该函数将返回 NULL,并且可以通过调用 GetLastError 函数找到错误代码。

注解

PFXImportCertStore 函数将打开一个临时存储。 如果该函数成功,则应通过调用 CertCloseStore 函数关闭存储的句柄。

从 PFX 数据包导入证书时,CSP/KSP 容器名称通过使用 PKCS8ShroudedKeyBag 的 OID 1.3.6.1.4.1.311.17.1 的 AttributeId 来确定 SafeBag [bagId: 1.2.840.113549.1.12.10.1.2] (有关此) 的 ASN.1 结构的详细信息,请参阅 PKCS #12

  • AttributeId: 1.3.6.1.4.1.311.17.1
  • 价值: KSP 名称或 CSP 名称

如果 AttributeId 不存在并且传递了PREFER_CNG标志,则选取MS_KEY_STORAGE_PROVIDER。 如果 AttributeId 不存在且未传递PREFER_CNG标志,则根据公钥算法确定提供程序名称 (即,公钥算法由 PKCS #8 中的 AlgorithmIdentifier 确定) :

  • Rsa: MS_ENHANCED_PROV_W
  • Dsa: MS_DEF_DSS_DH_PROV_W

同样,使用 AttributeId 和 OID 2.5.29.15 (szOID_KEY_USAGE) 确定密钥规范,如下所示:

如果使用 CAPI 密钥:

  • 如果设置了KEY_ENCIPHERMENT或DATA_ENCIPHERMENT,则密钥规范设置为AT_KEYEXCHANGE。
  • 如果设置了DIGITAL_SIGNATURE或CERT_SIGN或CRL_SIGN,则密钥规范设置为AT_SIGNATURE。

如果使用 CNG 密钥:

  • 如果设置了 KEY_ENCIPHERMENT 或 DATA_ENCIPHERMENT 或 ENCIPHER_ONLY 或 DECIPHER_ONLY,则 ncrypt 密钥用法设置为 ALLOW_DECRYPT。
  • 如果设置了DIGITAL_SIGNATURE或CERT_SIGN或CRL_SIGN,则 ncrypt 密钥用法设置为ALLOW_SIGN。
  • 如果设置了 KEY_AGREEMENT,则 ncrypt 密钥用法设置为 ALLOW_KEY_AGREEMENT。

如果 AttributeId 不存在,则对于 RSA 或 DH,CAPI 键值设置为 AT_KEYEXCHANGE,并且算法由 PKCS #8 中的 AlgorithmIdentifier 确定;否则,该算法设置为AT_SIGNATURE。 对于 CNG 键值,将设置所有 ncrypt 密钥用法。

注意

如果 PFX 数据包中存在无效的提供程序名称,或者此注册表项中不存在基本或增强的加密提供程序: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider,则提供程序类型使用此注册表子项执行提供程序查找: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider Types

Microsoft 仅支持两种用于导入 PFX 的加密/哈希算法:

  • TripleDES-SHA1
  • AES256-SHA256

对于上述任一算法,证书加密都是可选的。

Microsoft 可以通过选择从证书存储 All Tasks>Yes, export the private key 导出 PFX。 可以选择加密/哈希算法来匹配这两个选项之一。

可以使用 PowerShell 通过以下方法导出 PFX:

Export-PfxCertificate
[-CryptoAlgorithmOption <CryptoAlgorithmOptions>]

-CryptoAlgorithmOption 指定用于在 PFX 文件中加密私钥的算法。 如果未指定此参数,则默认值为 TripleDES_SHA1。 此参数的可接受值为:

说明
TripleDES_SHA1 私钥将使用三重 DES 加密在 PFX 文件中进行加密。
AES256_SHA256 将使用 AES-256 加密对 PFX 文件中的私钥进行加密。

OpenSSL 通过以下命令支持上述两种算法:

  • openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -in in.pem -export -out out.pfx -password file:password.txt -passin file:password.txt
  • openssl pkcs12 -keypbe AES-256-CBC -certpbe AES-256-CBC -macalg sha256 -in in.pem -export -out out.pfx -password file:password.txt -passin file:password.txt

以下命令等效于前两个命令,但它们不会加密证书:

  • openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe NONE -in in.pem -export -out out.pfx -password file:password.txt -passin file:password.txt
  • openssl pkcs12 -keypbe AES-256-CBC -certpbe NONE -macalg sha256 -in in.pem -export -out out.pfx -password file:password.txt -passin file:password.txt

要求

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

另请参阅

PFXExportCertStore

PFXExportCertStoreEx