首页 > 解决方案 > 使用 Wininet 的 Https 客户端身份验证,使用非持久性根证书

问题描述

我正在通过 https 与需要客户端身份验证的服务器通信。

为了使其工作,我必须使用Microsoft 管理控制台(mms)将服务器根证书导入 Windows 的全局证书存储。

但我试图让它安静地运行。

所以我的问题是:

如何告诉 Wininet 给定证书是根证书,以便它可以使用它来检查整个证书链?

(没有用户处理,也没有管理员权限,也没有系统级注册)

更多细节:

我有 (a) 证书 + (b) 我的客户的私钥。

我有(c)服务器的根证书。

我构建了一个包含 (a) 和 (b) 的 pfx 文件:

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -certfile root.pem -out test.pfx

现在我可以使用 test.pfx 来构建证书存储CS(使用PFXImportCertStore)。

在构建我的请求期间,我设置了来自CS的所有证书(使用InternetSetOption(INTERNET_OPTION_CLIENT_CERT_CONTEXT)

这是我的代码的一个非常简约的摘录:

CRYPT_INTEGER_BLOB blob ;
blob.pbData = ...pointer to a buffer containing test.pfx
blob.cbData = ...size of this buffer
HCERTSTORE cs = PFXImportCertStore( &blob,L"pw",PKCS12_NO_PERSIST_KEY ) ;
HINTERNET ses = InternetOpen("test",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0) ;
HINTERNET con = InternetConnect( ses,"server",4444,NULL,NULL,INTERNET_SERVICE_HTTP,0,NULL ) ;
HINTERNET req = HttpOpenRequest( con,"POST",NULL,NULL,NULL,NULL,INTERNET_FLAG_SECURE,NULL ) ;
PCCERT_CONTEXT pc = CertEnumCertificatesInStore( cs,0 ) ;
for (; pc ; pc = CertEnumCertificatesInStore( cs,pc ))
    InternetSetOption( req,INTERNET_OPTION_CLIENT_CERT_CONTEXT,(void*)pc,sizeof( CERT_CONTEXT )) ;
HttpSendRequest( req,NULL,0,NULL,0 ) ;

但它不能按原样工作。

我必须在 Windows 的证书存储中插入根证书 (c)。

此外,插入在 pfx 文件中的证书 (c) 是无用的。

我可以在openssl命令行中省略它。

由于我希望它静默运行,并且这个根证书只用于这个单独的请求一次,我想知道是否可以将它标记为root(在PFXImportCertStoreInternetSetOption步骤)?

PS我正在使用 Visual Studio 2017 / Windows 10 x64。

PPS这是我上一篇文章的续篇:Client authentication (certificat + private key) using WinInet

标签: c++authenticationsslhttpswininet

解决方案


推荐阅读