目录
1 背景
2 curl命令
3 libcurl 控制参数
4 双向认证
5 参考文档
在使用浏览器访问https链接时,浏览器会自动请求网站的安全证书,并进行证书校验,以及(使用证书)参与后续的通道加密逻辑。
而使用curl(不管是curl.exe命令行工具,还是使用libcurl库)请求https时,在curl的标准逻辑里面,它也会使用类似浏览器的流程,进行证书校验和加密,此时这个证书校验流程对于使用者来说,可能是需要定制的(譬如不校验,标准校验,甚至双向校验东等)。
本文主要讨论通过设置libcurl的参数,来控制这个校验过程。
2.1 忽略证书校验
curl --location "https://s.example.com/" --insecure
2.2 指定CA证书
curl --cacert "
3.1 CURLOPT_CAINFO
3.1.1 指定一个具体的CA证书路径(完整路径)
3.1.2 https://curl.se/libcurl/c/CURLOPT_CAINFO.html
3.1.3 e.g.
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/certs/cabundle.pem");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
3.2 CURLOPT_CAPATH
3.2.1 指定一个CA证书的路径(里面可以放置多个证书)
3.2.2 https://curl.se/libcurl/c/CURLOPT_CAPATH.html
3.3 CURLOPT_SSL_VERIFYPEER
3.3.1 https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html
3.3.2 是否校验服务器证书,设置为1(缺省值)表示校验,设置为0表示不校验
3.3.3 e.g.
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Set the default value: strict certificate check please */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_perform(curl);
}
3.4 CURLOPT_SSL_VERIFYHOST
3.4.1 https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
3.4.2 这个值配合3.3的CURLOPT_SSL_VERIFYPEER使用,标识校验服务器证书的哪些内容。设置为2(缺省值)表示既校验证书的有效性,并且要校验证书的Common Name和实际访问的域名是匹配的(也就是标准的严格校验)。设置为0则表示只校验证书的有效性,不校验证书的Common Name。
3.4.3 如果 CURLOPT_SSL_VERIFYPEER 设置为0,则设置 CURLOPT_SSL_VERIFYHOST 无意义(会被libcurl自动设置为0)。
3.4.4 另外一些历史原因,这个值 CURLOPT_SSL_VERIFYHOST 曾经可以设置为1,在新版libcurl里面已经废除,可以参考3.4.1的相关内容。
4.1 一般双向认证指客户端认证服务端,并且服务端也认证客户端。但是因为客户端认证服务端比较常见,这里只讨论服务端认证客户端的情形下,终端需要设置的参数,这种场景下客户端须向服务端提供自己的证书。
4.2 CURLOPT_SSLCERTTYPE
4.2.1 https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
4.2.2 指定终端证书的类型:一般是 "PEM" or "DER"。
4.3 CURLOPT_SSLCERT
4.3.1 https://curl.se/libcurl/c/CURLOPT_SSLCERT.html
4.3.2 指定终端证书的完整路径,一般是和 CURLOPT_SSLCERTTYPE 一起使用。
4.4 CURLOPT_SSLKEYTYPE
4.4.1 https://curl.se/libcurl/c/CURLOPT_SSLKEYTYPE.html
4.4.2 配合CURLOPT_SSLKEY使用,指定终端证书私钥类型,一般使用 "PEM" 格式
4.5 CURLOPT_SSLKEY
4.5.1 https://curl.se/libcurl/c/CURLOPT_SSLKEY.html
4.5.2 指定终端证书的私钥文件全路径(嘿,为什么要指定私钥?大家可以思考下!)。
4.6 CURLOPT_KEYPASSWD
4.6.1 https://curl.se/libcurl/c/CURLOPT_KEYPASSWD.html
4.6.2 指定私钥证书的密码,配合 CURLOPT_SSLKEY 使用。
4.6.3 e.g.
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem");
curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem");
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "superman");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
[1] linux c++ curl https 请求并双向验证SSL证书 https://www.cnblogs.com/yongpan/p/8084854.html
[2] 证书类型原理及转换方式 https://segmentfault.com/a/1190000011709784
[3] https双向认证 https://blog.csdn.net/u014644574/article/details/126190061
[4] HTTPS运行流程 https://zhuanlan.zhihu.com/p/60033345