[libcurl] 通过https访问百度的CA证书配置

想要通过libcurl使用https访问网址,需要配置CA证书。
这篇文章记录一下如何配置。

环境

VS2022 添加了libcurl库

不配置CA证书的https访问

代码:
主函数,指定了访问"https://www.baidu.com"

int main()
{
	curl_global_init(CURL_GLOBAL_WIN32);
	const char* url = "https://www.baidu.com";

	MyGetInfo(url);

	curl_global_cleanup();
	cout << "program end." << endl;
}

libcurl api实现访问,这里没有设置跟SSL有关的选项,
实际上是个http访问的代码。

int MyGetInfo(const char* url)
{
	double content_length;
	CURL* curl = curl_easy_init();
	if (curl) {		
		curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_HEADER, 1L);//仅HTTP头
		curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //在控制台显示详细信息

		CURLcode ret = curl_easy_perform(curl);
		if (ret != CURLE_OK) {
			curl_easy_cleanup(curl);
			return ERROR2("curl_easy_perform", ret);
		}
		else {
			//获取HTTP头中的CURLINFO_CONTENT_LENGTH_DOWNLOAD信息
			curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length);
		}
	}
	else {
		return ERROR("curl_easy_init");
	}
	curl_easy_cleanup(curl);
	return 0;
}

控制台输出执行结果(要设置CURLOPT_VERBOSE):

* Host www.baidu.com:443 was resolved.
* IPv6: 2409:8c20:6:1135:0:ff:b027:210c, 2409:8c20:6:1d55:0:ff:b09c:7d77
* IPv4: 36.155.132.76, 36.155.132.3
*   Trying [2409:8c20:6:1135:0:ff:b027:210c]:443...
* Connected to www.baidu.com (2409:8c20:6:1135:0:ff:b027:210c) port 443
* ALPN: curl offers h2,http/1.1
* SSL certificate problem: unable to get local issuer certificate
* Closing connection
?MyGetInfo@@YAHPEBD@Z curl_easy_perform 60 error
program end.

可以看到,试图访问目标443端口,但是因为
SSL certificate problem: unable to get local issuer certificate
失败了。

忽略CA证书的https访问

修改代码:

int MyGetInfo(const char* url)
{
	double content_length;
	CURL* curl = curl_easy_init();
	if (curl) {		
		curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_HEADER, 1L);//仅HTTP头,不要数据
		curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //在控制台显示详细信息
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //新增
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);//新增

		CURLcode ret = curl_easy_perform(curl);
		if (ret != CURLE_OK) {
			curl_easy_cleanup(curl);
			return ERROR2("curl_easy_perform", ret);
		}
		else {
			//获取HTTP头中的CURLINFO_CONTENT_LENGTH_DOWNLOAD信息
			curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length);
		}
	}
	else {
		return ERROR("curl_easy_init");
	}
	curl_easy_cleanup(curl);
	return 0;
}

新增了以下代码:

	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //新增  
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);//新增  

CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST要一起设置,
都设置为0的时候,将忽略对CA证书的检查。

libcurl API解释:
CURLOPT_SSL_VERIFYHOST
When the verify value is 0, the connection succeeds regardless of the names in the certificate. Use that ability with caution!

CURLOPT_SSL_VERIFYPEER
When this option is disabled (set to zero), the CA certificates are not loaded and the peer certificate verification is simply skipped.

控制台输出执行结果(要设置CURLOPT_VERBOSE):

* Host www.baidu.com:443 was resolved.
* IPv6: 2409:8c20:6:1135:0:ff:b027:210c, 2409:8c20:6:1d55:0:ff:b09c:7d77
* IPv4: 36.155.132.76, 36.155.132.3
*   Trying [2409:8c20:6:1135:0:ff:b027:210c]:443...
* Connected to www.baidu.com (2409:8c20:6:1135:0:ff:b027:210c) port 443
* ALPN: curl offers h2,http/1.1
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: C=CN; ST=beijing; L=beijing; O=Beijing Baidu Netcom Science Technology Co., Ltd; CN=baidu.com
*  start date: Jul  6 01:51:06 2023 GMT
*  expire date: Aug  6 01:51:05 2024 GMT
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
> HEAD / HTTP/1.1
Host: www.baidu.com
Accept: */*

< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Cache-Control: no-cache
Cache-Control: no-cache
< Connection: keep-alive
Connection: keep-alive
< Content-Length: 227
Content-Length: 227
< Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
< Content-Type: text/html
Content-Type: text/html
< Date: Mon, 25 Dec 2023 05:50:16 GMT
Date: Mon, 25 Dec 2023 05:50:16 GMT
< Pragma: no-cache
Pragma: no-cache
< Server: BWS/1.1
Server: BWS/1.1
< Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
< Set-Cookie: PSTM=1703483416; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1703483416; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
< Set-Cookie: BAIDUID=2CF2E2EBB535C6E704A28FC977754E61:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000
Set-Cookie: BAIDUID=2CF2E2EBB535C6E704A28FC977754E61:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000
< Set-Cookie: BAIDUID_BFESS=2CF2E2EBB535C6E704A28FC977754E61:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None
Set-Cookie: BAIDUID_BFESS=2CF2E2EBB535C6E704A28FC977754E61:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None
< Traceid: 1703483416046571265014818631086766562759
Traceid: 1703483416046571265014818631086766562759
< X-Ua-Compatible: IE=Edge,chrome=1
X-Ua-Compatible: IE=Edge,chrome=1

<
* Connection #0 to host www.baidu.com left intact
program end.

可以看到,成功通过443端口通信了。但是仍然有以下一句log:
SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.

配置CA证书的https访问

首先获取百度的CA证书。
通过浏览器(我用的edge)访问百度。
在这里插入图片描述
点击地址栏左侧的小锁头图标,选择连接安全
在这里插入图片描述
点击右上角的证书图标,
在这里插入图片描述
证书查看器详细信息中,右下角导出,可以保存.crt文件文件到本地,到处完成后我给改成.pem文件了。

代码:

int MyGetInfo(const char* url)
{
	double content_length;
	CURL* curl = curl_easy_init();
	if (curl) {		
		curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_HEADER, 1L);//仅HTTP头,不要数据
		curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //在控制台显示详细信息
		//https
		CURLcode err = curl_easy_setopt(curl, CURLOPT_CAINFO, "D:\\SourceCode\\http_file_download_vc\\http_libcurl_head_test_vc\\http_libcurl_head_test_vc\\baidu.pem"); //新增
		if (err != CURLE_OK) {
			cout << "CURLOPT_CAPATH err:" << err << endl;
		}
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); //新增
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);//新增

		CURLcode ret = curl_easy_perform(curl);
		if (ret != CURLE_OK) {
			curl_easy_cleanup(curl);
			return ERROR2("curl_easy_perform", ret);
		}
		else {
			//获取HTTP头中的CURLINFO_CONTENT_LENGTH_DOWNLOAD信息
			curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length);
		}
	}
	else {
		return ERROR("curl_easy_init");
	}
	curl_easy_cleanup(curl);
	return 0;
}

通过CURLOPT_CAINFO设置了.pem文件的绝对路径
CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST也都激活了。

控制台输出执行结果(要设置CURLOPT_VERBOSE):

* Host www.baidu.com:443 was resolved.
* IPv6: 2409:8c20:6:1135:0:ff:b027:210c, 2409:8c20:6:1d55:0:ff:b09c:7d77
* IPv4: 36.155.132.76, 36.155.132.3
*   Trying [2409:8c20:6:1135:0:ff:b027:210c]:443...
* Connected to www.baidu.com (2409:8c20:6:1135:0:ff:b027:210c) port 443
* ALPN: curl offers h2,http/1.1
*  CAfile: D:\SourceCode\http_file_download_vc\http_libcurl_head_test_vc\http_libcurl_head_test_vc\baidu.pem
*  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: C=CN; ST=beijing; L=beijing; O=Beijing Baidu Netcom Science Technology Co., Ltd; CN=baidu.com
*  start date: Jul  6 01:51:06 2023 GMT
*  expire date: Aug  6 01:51:05 2024 GMT
*  subjectAltName: host "www.baidu.com" matched cert's "*.baidu.com"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify ok.
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
> HEAD / HTTP/1.1
Host: www.baidu.com
Accept: */*

< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Cache-Control: no-cache
Cache-Control: no-cache
< Connection: keep-alive
Connection: keep-alive
< Content-Length: 227
Content-Length: 227
< Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
< Content-Type: text/html
Content-Type: text/html
< Date: Mon, 25 Dec 2023 05:58:59 GMT
Date: Mon, 25 Dec 2023 05:58:59 GMT
< Pragma: no-cache
Pragma: no-cache
< Server: BWS/1.1
Server: BWS/1.1
< Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
< Set-Cookie: PSTM=1703483939; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1703483939; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
< Set-Cookie: BAIDUID=F12F8B0D2BD1D3F50FB25A3C594BAA7D:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000
Set-Cookie: BAIDUID=F12F8B0D2BD1D3F50FB25A3C594BAA7D:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000
< Set-Cookie: BAIDUID_BFESS=F12F8B0D2BD1D3F50FB25A3C594BAA7D:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None
Set-Cookie: BAIDUID_BFESS=F12F8B0D2BD1D3F50FB25A3C594BAA7D:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None
< Traceid: 1703483939153945447410347613991833952090
Traceid: 1703483939153945447410347613991833952090
< X-Ua-Compatible: IE=Edge,chrome=1
X-Ua-Compatible: IE=Edge,chrome=1

<
* Connection #0 to host www.baidu.com left intact
program end.

可以看到,SSL校验SSL certificate verify ok.,是成功校验了证书的。
通过wireshark,也可以看到通信流程:
在这里插入图片描述

参考文章

libcurl:https认证控制参数简介

  • 47
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值