我编写了一个程序,该程序应该使用 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 说:
"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."
..我承认,我不是很明白。
当我恢复证书时,我使用 CertFindCertificateInStore() 来查看证书是否已经存在,只有当它不存在时我才这样做:
bOK = CertAddCertificateContextToStore(
hDestinationStore,
pCertContext,
CERT_STORE_ADD_USE_EXISTING,
NULL);
要重新添加证书...所以我的问题是,为什么不能保留私钥?我错过了什么吗?
最佳答案
您使用了错误的 CryptoAPI。你应该使用 PFXExportCertStoreEx和 PFXImportCertStore相反。
已更新:功能很常用。您当然不能从 SmartCard 导出证书或其他不可导出的证书。函数中的BLOG不过是PFX文件的contain。例如,从 PFX 文件导入证书应该执行以下操作:
- 打开 PFX 文件并读取内存中的完整内容。您当然可以改用文件映射。
- 您可以选择使用
PFXIsPFXBlob
函数来验证文件是否确实包含与 PFX 文件相对应的内容。 - 您使用
PFXImportCertStore
打开 BLOB (PFX) 作为源证书存储。 - 您使用
CertOpenStore
或其他一些函数打开您要保存 PFX 文件中的证书的目标证书存储。 - 您使用
CertEnumCertificatesInStore
枚举来自源证书存储 (PFX) 的证书,对于所有证书,使用CertAddCertificateContextToStore
将来自源证书存储的证书添加到目标证书存储.带有私钥的证书将与私钥一起导入。 - 您使用
CertCloseStore
关闭两个打开的存储。
关于windows - 使用 MS CryptoAPI 保存/恢复证书会使附加的私钥无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5741519/