1

我编写了一个程序,该程序应该使用 windows Crypto API 保存和恢复用户证书。我的印象是它工作正常,但现在用户抱怨证书恢复后附加到证书的私钥无效。

我正在使用以下方法保存证书:

HCERTSTORE hCertStore =
    CertOpenStore(CERT_STORE_PROV_PHYSICAL_W,
    0,
    NULL,
    CERT_SYSTEM_STORE_CURRENT_USER |
    CERT_STORE_OPEN_EXISTING_FLAG |
    CERT_STORE_READONLY_FLAG |
    CERT_STORE_UPDATE_KEYID_FLAG,
    (PVOID) storeName.c_str());

然后后来:

if (!CertSaveStore(hCertStore,
    0,
    CERT_STORE_SAVE_AS_STORE,
    CERT_STORE_SAVE_TO_FILENAME,
    (PVOID) saveFile.c_str(),
    0))

我知道 CERT_STORE_SAVE_AS_STORE 标志应该意味着整个证书应该被序列化,包括私钥。虽然我注意到 MSDN 说:

“CERT_KEY_CONTEXT_PROP_ID 属性和相关的 CERT_KEY_PROV_HANDLE_PROP_ID 和 CERT_KEY_SPEC_PROP_ID 值不会保存到序列化存储中。”

..我承认,我不太明白。

当我恢复证书时,我使用 CertFindCertificateInStore() 来查看证书是否已经存在,并且只有当它不存在时才这样做:

bOK = CertAddCertificateContextToStore(
    hDestinationStore,
    pCertContext,
    CERT_STORE_ADD_USE_EXISTING,
    NULL);

重新添加证书......所以我的问题是,为什么不能保留私钥?我错过了什么吗?

4

1 回答 1

4

你使用了错误的 CryptoAPI。您应该改用PFXExportCertStoreExPFXImportCertStore

更新:这些功能很常见。当然,您不能从 SmartCard 或其他不可导出的证书中导出证书。函数中的 BLOG 只不过是 PFX 文件的包含。例如,从 PFX 文件导入证书应该执行以下操作:

  1. 打开 PFX 文件并读取内存中的完整内容。您当然可以改用文件映射。
  2. 或者,您可以使用PFXIsPFXBlob函数来验证文件是否确实包含对应于 PFX 文件的内容。
  3. 您使用PFXImportCertStore打开 BLOB(PFX)作为源证书存储。
  4. 您使用CertOpenStore或其他一些功能来打开要保存 PFX 文件中的证书的目标证书存储。
  5. 您用于CertEnumCertificatesInStore枚举来自源证书存储 (PFX) 的证书,并用于将所有证书CertAddCertificateContextToStore从源证书存储添加到目标证书存储。具有私钥的证书将与私钥一起导入。
  6. 您使用CertCloseStore关闭两个打开的商店。
于 2011-04-21T09:06:50.847 回答