c++ - 使用 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(在PFXImportCertStore
或InternetSetOption
步骤)?
PS我正在使用 Visual Studio 2017 / Windows 10 x64。
PPS这是我上一篇文章的续篇:Client authentication (certificat + private key) using WinInet。
解决方案
推荐阅读
- c++ - 为什么 KCacheGrind 不显示我的函数名称?
- python - 使用大于或小于时如何执行while循环
- c# - 在 C# 控制台应用程序中删除控制台键入的文本
- python - 有没有办法处理 Window 的命令行错误?
- proftpd - 如何在 ProFTPD 上实现没有表的静态/固定 SQLGroupInfo?
- javascript - 在异步调用和共享变量之间
- javascript - 使用 javascript 对 HTML 表的项目进行分类
- gcc - 这是 GCC 错误还是我做错了什么?
- mysql - 分组和排序计数 desc 花费时间
- windows-10-universal - 错误:我的新类的当前上下文中不存在名称“FindName”