Wininet库忽略Https证书
相信很多朋友使用C++ WINAPI开发的时候网络模块的时候遇到Https忽悠证书无效的情况下,
仍然希望获取结果下列代码便是忽略异常的Https CA证书,下面对原理进行简单的讲解首先,
需要设置Https忽略需要用到如下结果函数与参数InternetQueryOptionA/InternetSetOptionA
参数需要SECURITY_FLAG_IGNORE_UNKNOWN_CA,下面建议先阅读下代码可以发现忽略Https证书
是发生在HttpSendRequestA之后设置这是因为InternetConnect主要负责主要负责建立与服务器
的连接,而涉及到CA(Certificate Authority)的验证通常是在建立连接后的HTTP请求阶段进行的,
CA的验证是在SSL/TLS握手过程中完成的,而握手过程通常是在 HttpSendRequestA被调用时发生。
因此,在建立连接时,我们还没有进入HTTP请求的阶段,所以无法在 InternetConnect 之前
处理CA验证的问题,因此下列代码是进行这样忽略的首先HttpSendRequestA返回ERROR_INTERNET_INVALID_CA
出现CA证书异常这个时候需要忽略证书无效,InternetQueryOptionA获取当前的安全选项然后
追加上SECURITY_FLAG_IGNORE_UNKNOWN_CA忽略证书无效CA将设置后的值通过InternetSetOptionA
函数应用再次发起HttpSendRequestA即可忽略CA证书进行下一步操作。
#include
#include
#include
#pragma comment(lib, "wininet.lib")
#define TRANSFER_SIZE 1024
bool PerformHttpRequest() {
LPCSTR lpszAgent = "";
HINTERNET hInternet = InternetOpenA(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hInternet) {
return false;
}
LPCSTR lpszServerName = "192.168.99.111";
INTERNET_PORT nServerPort = INTERNET_DEFAULT_HTTPS_PORT;
LPCSTR lpszUserName = NULL;
LPCSTR lpszPassword = NULL;
DWORD dwConnectFlags = 0;
DWORD dwConnectContext = 0;
HINTERNET hConnect = InternetConnectA(hInternet,
lpszServerName, nServerPort,
lpszUserName, lpszPassword,
INTERNET_SERVICE_HTTP,
dwConnectFlags, dwConnectContext);
if (!hConnect) {
InternetCloseHandle(hInternet);
return false;
}
LPCSTR lpszVerb = "GET";
LPCSTR lpszObjectName = "/Login";
LPCSTR lpszVersion = NULL;
LPCSTR lpszReferrer = NULL;
LPCSTR* lplpszAcceptTypes = NULL;
DWORD dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_AUTH |
INTERNET_FLAG_NO_COOKIES |
INTERNET_FLAG_NO_UI |
INTERNET_FLAG_SECURE |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
INTERNET_FLAG_RELOAD;
DWORD dwOpenRequestContext = 0;
HINTERNET hRequest = HttpOpenRequestA(hConnect, lpszVerb, lpszObjectName, lpszVersion,
lpszReferrer, lplpszAcceptTypes,
dwOpenRequestFlags, dwOpenRequestContext);
if (!hRequest) {
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
BOOL bResult = HttpSendRequestA(hRequest, NULL, 0, NULL, 0);
if (!bResult && GetLastError() == ERROR_INTERNET_INVALID_CA) {
DWORD dwFlags;
DWORD dwBuffLen = sizeof(dwFlags);
InternetQueryOptionA(hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOptionA(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags));
bResult = HttpSendRequestA(hRequest, NULL, 0, NULL, 0);
}
if (!bResult) {
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
char szBuff[TRANSFER_SIZE];
DWORD dwReadSize = TRANSFER_SIZE;
bResult = HttpQueryInfoA(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, szBuff, &dwReadSize, NULL);
if (!bResult) {
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
szBuff[dwReadSize] = '\0';
printf("%s\n", szBuff);
DWORD dwBytesAvailable;
bResult = InternetQueryDataAvailable(hRequest, &dwBytesAvailable, 0, 0);
if (!bResult) {
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
if (dwBytesAvailable > TRANSFER_SIZE) {
printf("数据太长 %d /b", GetLastError(), dwBytesAvailable);
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
DWORD dwBytesRead;
bResult = InternetReadFile(hRequest, szBuff, dwBytesAvailable, &dwBytesRead);
if (!bResult) {
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return false;
}
szBuff[dwBytesRead] = '\0';
printf("%s\n", szBuff);
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return true;
}
int main() {
if (PerformHttpRequest()) {
return 0;
}
else {
return 1;
}
}