使用WinInet的客户端身份验证(证书+私钥)

问题描述 投票:2回答:1
  • 这是我的previous question的演变,这是关于WinHttp。
  • 我希望这是正确的方法......

我正在尝试使用WinInet(来自Win32 API)与服务器进行https通信。

这是一个极简主义的代码:

HINTERNET ses = InternetOpen("test",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0) ;
HINTERNET con = InternetOpenUrl( ses,"https://stackoverflow.com",NULL,0,0,0 ) ;
DWORD read ;
char  str [3000] ;
InternetReadFile( con,reinterpret_cast<void*>( str ),sizeof( str )-1,&read ) ;
str[read] = 0 ;
cout << &str[0] ;
InternetCloseHandle( con ) ;
InternetCloseHandle( ses ) ;

只要我与“经典”https服务器(如stackoverflow.com)进行通信,一切顺利。问题是当我尝试与请求客户端身份验证的服务器通信时。

我有3个.pem文件:我的客户端的证书和私钥,以及验证我的客户端证书的根证书(即长度为2的证书链)。

有关信息,我可以使用此cULR命令行连接我的服务器:

curl https://my.server --cert Client_cert.pem --key Client_key.pem --cacert Root_cert.pem

这证明它是可能的!

阅读WinInet文档后,我找到了一个名为“Handling Authentication”的页面,但它完全是关于用户名:密码,而且没有关于证书的内容。

我发现我必须使用Crypt32库:我必须使用CertCreateCertificateContext创建证书上下文,然后将其插入certificat商店,然后使用该商店进行连接......好吧,我必须承认我会很高兴找到一个很好的教程或一些代码示例!顺便说一句,我没有关于如何将我的私钥插入那些东西的线索......

提前致谢 !

c++ ssl winapi https wininet
1个回答
0
投票

您必须使用INTERNET_OPTION_CLIENT_CERT_CONTEXT将您的证书传递给WinInet并调用InternetSetOption()

INTERNET_OPTION_CLIENT_CERT_CONTEXT

84

InternetQueryOption不支持此标志。 lpBuffer参数必须是指向CERT_CONTEXT结构的指针,而不是指向CERT_CONTEXT指针的指针。如果应用程序收到ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,则必须在重试请求之前调用InternetErrorDlg或使用InternetSetOption提供证书。然后调用CertDuplicateCertificateContext,以便应用程序可以独立发布传递的证书上下文。

所以,例如:

InternetSetOption(hI,INTERNET_OPTION_CLIENT_CERT_CONTEXT,(void*)cert,sizeof(CERT_CONTEXT));

顺便说一句,curl调用不是很好的例子,因为curl使用的是使用OpenSSL的libcurl

© www.soinside.com 2019 - 2024. All rights reserved.