我不知道这是否是最好的方法,但至少它对我有用(我假设您要导入当前用户的存储而不是机器证书存储)。
首先,您必须将 PFX 文件加载到 CRYPT_DATA_BLOB 中(它是一个包含指向缓冲区的指针和相关长度的结构)。基本上,您将 PFX 读入缓冲区并相应地设置长度。然后,您可以使用 PFXImportCertStore 将该 CRYPT_DATA_BLOB 导入证书存储区。这个证书存储是一个临时的,所以它还没有进入你想要的证书存储。然后,您必须打开要真正将证书导入的证书存储(通过使用 CertOpenSystemStore),使用 CertEnumCertificatesInStore 从临时证书存储中提取证书对象,然后使用 CertAddCertificateContextToStore 将其插入最终证书存储。
这段代码或多或少地显示了以上所有内容:
#include <Windows.h>
#include <wincrypt.h>
int main(int argc, char** argv) {
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
unsigned char buffer[8192];
CRYPT_DATA_BLOB key;
key.cbData = 0;
key.pbData = buffer;
HANDLE h = CreateFile(L"c:\\temp\\server.pfx", FILE_GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
ReadFile(h, buffer, 8192, &key.cbData, NULL);
CloseHandle(h);
HCERTSTORE store = PFXImportCertStore(&key, L"mypassword", 0);
PCCERT_CONTEXT ctx = CertEnumCertificatesInStore(store, NULL);
HCERTSTORE rootStore = CertOpenSystemStore(NULL, L"ROOT");
CertAddCertificateContextToStore(rootStore, ctx, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
CertCloseStore(store, 0);
CertCloseStore(rootStore, 0);
return 0;
}
为简洁起见,代码不包含任何错误检查。它还假设临时存储中只有一个证书(否则您应该将 CertEnumCertificatesInStore 放在一个循环中)。无论如何,我认为您可以从这里构建(您应该检查许多方法的可用选项)。
记得将 crypt32.lib 添加到项目中。