使用 MS CryptoAPI 保存/恢复证书会使附加的私钥无效 [英] Saving/Restoring certs with MS CryptoAPI invalidates attached private key

查看:9
本文介绍了使用 MS CryptoAPI 保存/恢复证书会使附加的私钥无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've written a program which is supposed to save and restore a users certificates using the windows Crypto API. I was under the impression that it was working fine but now a user has complained that the private key that was attached to the certificate is invalid after the cert has been restored.

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

I was saving the certificates using:

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 说:

I understand that the CERT_STORE_SAVE_AS_STORE flag should mean that the entire cert should get serialized including the private key. Although I note that MSDN says:

CERT_KEY_CONTEXT_PROP_ID 属性和相关的CERT_KEY_PROV_HANDLE_PROP_ID 和CERT_KEY_SPEC_PROP_ID 值不是保存到序列化存储中."

"The CERT_KEY_CONTEXT_PROP_ID property and the related CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_SPEC_PROP_ID values are not saved to a serialized store."

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

..which I confess, I don't really understand.

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

When I restore the cert I use CertFindCertificateInStore() to see if the cert is already present and only if it isn't I do:

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

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

To add the certificate back... So my question is, why might the private key not be preserved? Am I missing something?

推荐答案

你使用了错误的 CryptoAPI.您应该使用 PFXExportCertStoreExPFXImportCertStore 代替.

You use wrong CryptoAPI. You should use PFXExportCertStoreEx and PFXImportCertStore instead.

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

UPDATED: The functions are very common. You can not export certificates from the SmartCard of course or other non-exportable certificates. The BLOG in the function is nothing more as the contain of the PFX file. For example the import of the certificate from PFX file should do the following:

  1. 打开 PFX 文件并读取内存中的全部内容.您当然可以改用文件映射.
  2. 您可以选择使用 PFXIsPFXBlob 函数来验证文件是否确实包含对应于 PFX 文件的内容.
  3. 您使用 PFXImportCertStore 打开 BLOB(PFX)作为源证书存储.
  4. 您使用 CertOpenStore 或其他函数打开目标证书存储区,您希望在其中保存 PFX 文件中的证书.
  5. 您使用 CertEnumCertificatesInStore 枚举来自源证书存储 (PFX) 的证书,对于所有证书,使用 CertAddCertificateContextToStore 将证书从源证书存储添加到目标证书存储.具有私钥的证书将与私钥一起导入.
  6. 您使用 CertCloseStore 关闭两个已打开的商店.
  1. Open the PFX file and read full contain in the memory. You can use of course the file mapping instead.
  2. Optionally you can use PFXIsPFXBlob function to verify that the file has really contain which corresponds to the PFX file.
  3. You use PFXImportCertStore to open the BLOB (the PFX) as the source certificate store.
  4. You use CertOpenStore or some other function to open the destination certificate store where you want save the certificates from the PFX file.
  5. You use CertEnumCertificatesInStore to enumerate certificates from the source certificate store (PFX) and for all certificate use CertAddCertificateContextToStore to add certificate from the source certificate store to the destination certificate store. The certificates having private key will be imported with the private key.
  6. You use CertCloseStore to close both opened stores.

这篇关于使用 MS CryptoAPI 保存/恢复证书会使附加的私钥无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆