使用 MS CryptoAPI 保存/恢复证书会使附加的私钥失效

发布于 2024-11-02 15:51:11 字数 1082 浏览 6 评论 0原文

我编写了一个程序,该程序应该使用 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);

添加证书回来了...所以我的问题是,为什么私钥可能不会被保留?

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());

And then later:

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

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:

"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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谷夏 2024-11-09 15:51:11

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

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

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

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

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. 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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文