一、配置curl https請求須要提供 CA證書、客戶端證書和客戶端祕鑰,這三個文件的pem格式。html
分別對應 curl_easy_setopt() 函數的 下面三個參數:ios
CURLOPT_CAINFO - path to Certificate Authority (CA) bundle
CURLOPT_SSLKEY - specify private keyfile for TLS and SSL client cert
CURLOPT_SSLCERT - set SSL client certificatejson
通常建立SSL證書時會生成 ca.crt , client.crt, client.key, server.crt, server.key 等,而 curl客戶端請求,只須要將 ca.crt , client.crt, client.key轉成相應的 pem格式 使用。轉換方法以下:segmentfault
1)將 CRT 轉成 PEM---
不能直接將 .crt 轉成 .pem,須要通過 .der 中轉windows
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 中轉 app
openssl rsa -in client.key -out client.der -outform DER openssl rsa -inform DER -outform PEM -in client.der -out client_key.pem
二、配置 curl https請求curl
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 certificatethis
按下面代碼部分進行配置,便可訪問
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 -1; 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, 8); 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