1、配置curl https请求需要提供 CA证书、客户端证书和客户端秘钥,这三个文件的pem格式。

  分别对应 curl_easy_setopt() 函数的 下面三个参数:

  CURLOPT_CAINFO - path to Certificate Authority (CA) bundle
  CURLOPT_SSLKEY - specify private keyfile for TLS and SSL client cert
  CURLOPT_SSLCERT - set SSL client certificate

一般创建SSL证书时会生成 ca.crt , client.crt, client.key, server.crt, server.key 等,而 curl客户端请求,只需要将 ca.crt , client.crt, client.key转成相应的 pem格式 使用。转换方法如下:

  1)将 CRT 转成 PEM---
    不能直接将 .crt 转成 .pem,需要经过 .der 中转

   openssl x509 -in client.crt -out client.der -outform der
   openssl x509 -in client.der -inform der -outform pem -out client.pem    openssl x509 -in ca.crt -out ca.der -outform der
   openssl x509 -in ca.der -inform der -outform pem -out ca_info.pem

  2)将 .key 转成 .pem

    不能直接将 .key 转成 .pem,需要经过 .der 中转    

   openssl rsa -in client.key -out client.der -outform DER
   openssl rsa -inform DER -outform PEM -in client.der -out client_key.pem

2、配置 curl https请求

  1) 官方例程如下:
  curl 接口文档说明:
   https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
   https://curl.haxx.se/libcurl/c/CURLOPT_CAINFO.html
      https://curl.haxx.se/libcurl/c/https.html

  CURLOPT_CAINFO - path to Certificate Authority (CA) bundle
  CURLOPT_SSLKEY - specify private keyfile for TLS and SSL client cert
  CURLOPT_SSLCERT - set SSL client certificate

按下面代码部分进行配置,即可访问

    CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");   // 下面两个为验证对方和验证主机名,若为0,则跳过验证,我这个服务器必须验证才能得到请求数据
  curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);
  curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 1L);    
    
// 配置 https 请求所需证书
  curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/certs/cabundle.pem");
  curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem");
  curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem");
  curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret");   ret = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
  }

  2)我的代码如下

  这是一个完整的 curl 发送 https get 请求,并带中文参数  

#include <iostream>
#include <sstream>
#include <jsoncpp/json/json.h>
#include <curl/curl.h>
#include <exception>
#include <string>
#include <iostream>
#include <stdlib.h> int writer(char *data, size_t size, size_t nmemb, string *writerData)
{
  unsigned long sizes = size * nmemb;
  if (writerData == NULL)
  return -;   writerData->append(data, sizes);
  return sizes;
} string parseJsonResponse_question(string input)
{
Json::Value root;
Json::Reader reader;
bool parsingSuccessful = reader.parse(input, root);
if(!parsingSuccessful)
{
std::cout<<"!!! Failed to parse the response data"<< std::endl;
return "";
}
const Json::Value text = root["obj"]["question"];
string result = text.asString();
return result;
} string HttpsGetRequest_question(string input)
{
string buffer, ling_result; // 对请求参数中的中文和特殊字符(如空格等)进行处理,方可使用
char * escape_control = curl_escape(input.c_str(), input.size());
input = escape_control;
curl_free(escape_control); string str_url= "https://*.*.*.*/question?question=" + input; // alter *.*.*.* by your server address try
{
CURL *pCurl = NULL;
CURLcode res; // In windows, this will init the winsock stuff
curl_global_init(CURL_GLOBAL_ALL);
// get a curl handle
pCurl = curl_easy_init();
if (NULL != pCurl)
{
// 设置超时时间为8秒
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, );
curl_easy_setopt(pCurl, CURLOPT_URL, str_url.c_str()); // 下面两个为验证对方和验证主机名,若为0,则跳过验证,我这个服务器必须验证才能得到请求数据
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 1L); // 配置 https 请求所需证书
curl_easy_setopt(pCurl,CURLOPT_CAINFO,"/etc/msc/ca_info.pem");
curl_easy_setopt(pCurl, CURLOPT_SSLCERT, "/etc/msc/client.pem");
curl_easy_setopt(pCurl, CURLOPT_SSLKEY, "/etc/msc/client_key.pem");
curl_easy_setopt(pCurl, CURLOPT_KEYPASSWD, "your_key_password"); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &buffer); // Perform the request, res will get the return code
res = curl_easy_perform(pCurl);
// Check for errors
if (res != CURLE_OK)
{
printf("curl_easy_perform() failed:%s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(pCurl);
}
curl_global_cleanup();
}
catch (std::exception &ex)
{
printf("curl exception %s.\n", ex.what());
}
if(buffer.empty())
{
std::cout<< "!!! ERROR The sever response NULL" << std::endl;
}
else
{
ling_result = parseJsonResponse_question(buffer);
}
return ling_result;
}

参考:

  http://blog.csdn.net/rztyfx/article/details/6919220
  https://segmentfault.com/a/1190000011709784

linux c++ curl https 请求并双向验证SSL证书的更多相关文章

  1. 请求https前缀的网站验证SSL证书的解决方案之一

    from requests.packages.urllib3.exceptions import InsecureRequestWarning # 禁用安全请求警告requests.packages. ...

  2. Requests对HTTPS请求验证SSL证书

    SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socket layer(SSL)安全协议是由Netscape Communication公司设计开发.该安全协议主 ...

  3. .Net Core 发送https请求/.net core 调用数字证书 使用X509Certificate2

    .Net Core 发送https请求 .net core 调用数字证书 使用X509Certificate2 .NET下面的 .netfromwork使用和asp.net core下使用方式不一样 ...

  4. TortoiseGit 访问https远程仓库,上报SSL证书错误解决方法

    报错 在使用TortoiseGit时,clone自己搭建的gitlab报如错SSL certificate problem: self signed certificate 原因:自行搭建的gitla ...

  5. Https系列之一:https的简单介绍及SSL证书的生成

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  6. linux下Tomcat+OpenSSL配置单向&双向认证(自制证书)

    背景 由于ios将在2017年1月1日起强制实施ATS安全策略,所有通讯必须使用https传输,本文只针对自制证书,但目前尚不确定自制证书是否能通过appstore审核. 1.必须支持传输层安全(TL ...

  7. linux tomcat【9.0.12】 使用 ssl证书 配置 https 的具体操作 【使用 域名 】

    1.前言 根据上一个随笔,已经可以正式在 阿里云服务器发布 工程了 ,但是用的协议默认是 http ,端口80 但是 http不安全 ,容易被拦截抓包 ,于是出来了个 https tomcat发布 对 ...

  8. [从零开始搭网站六]为域名申请免费SSL证书(https),并为Tomcat配置https域名所用的多SSL证书

    点击下面连接查看从零开始搭网站全系列 从零开始搭网站 由于国内的网络环境比较恶劣,运营商流量劫持的情况比较严重,一般表现为别人打开你的网站的时候会弹一些莫名其妙的广告...更过分的会跳转至别的网站. ...

  9. postman进行https接口测试所遇到的ssl证书问题,参考别人方法

    参考文档: https://learning.getpostman.com/docs/postman/sending_api_requests/certificates/ 随着 https 的推动,更 ...

随机推荐

  1. kali蓝牙渗透

    1.hcitool 通过前面讲的升级操作后,在BackTrack4 Linux或者Ubuntu系统下将会安装好蓝牙的全套操作工具,其中就包括hcitool.该工具支持大量的蓝牙设备操作,从扫描到查看设 ...

  2. NOIP2009(codevs1173)最优贸易

    题目大意:给你一张有n个点m条边的有向图,每个点有一个权值,求一条1到n的路径,使得这条路径上存在两个点且他们的权值差最大. 思路:用dis[i]]记录从1到i的路径中所能得到两点间权值差的最大值,然 ...

  3. ASP.NET页面之间传值的方式之Application(个人整理)

    Application  Application变量在整个应用程序生命周期中都是有效的,类似于使用全局变量一样,所以可以在不同页面中对它进行存取.它和Session变量的区别在于,前者是所有的用户共用 ...

  4. py-faster-rcnn

    踩坑: 1. 服务器上训练: sh ./experiments/scripts/faster_rcnn_end2end.sh 会各种报错 有说是因为#!/bin/bash的问题,改过,不行. 改成如下 ...

  5. java.lang.ClassCastException: com.sun.proxy.$Proxy* cannot be cast to***

    Spring AOP 有两种代理方法, 一种是常规JDK,一种是CGLIB. 当代理对象实现了至少一个接口时,默认使用JDK动态创建代理对象: 当代理对象没有实现任何接口时,就会使用CGLIB方法. ...

  6. jQuery 字符串拼接

    jQuery 字符串拼接 // 字符串加变量拼接 $('#id 标签名[属性名="' + 变量 + '"]')

  7. Python 协程并发爬虫网页

    简单爬虫实例: 功能:通过urllib.request实现网站爬虫,捕获网站内容. from urllib import request def f(url): print("GET:%s& ...

  8. MYSQL 修改表结构基本操作一览

    查看表的字段信息:desc 表名; 查看表的所有信息:show create table 表名; 添加主键约束:alter table 表名 add constraint 主键 (形如:PK_表名) ...

  9. MySQL教程 3.3

    本实验是将数据加载到表中,具体步骤如下: 先创建数据库menagerie,再启用数据库,然后在库中创建表pet. 运行如下代码,将文本文件pet.txt加载到pet表中,但出现ERROR 1148.查 ...

  10. HBase运维实践-聊聊RIT的那点事

    相信长时间运维HBase集群的童鞋肯定都会对RIT(Region-In-Transition,很多参考资料误解为Region-In-Transaction,需要注意)有一种咬牙切齿的痛恨感,一旦Reg ...