https圖解:
1、客戶端向服務端發送SSL協議版本號、加密算法種類、隨機數等信息。
2、服務端給客戶端返回SSL協議版本號、加密算法種類、隨機數等信息,同時也返回服務器端的證書,即公鑰證書
3、客戶端使用服務端返回的信息驗證服務器的合法性,包括:
證書是否過期
發型服務器證書的CA是否可靠
返回的公鑰是否能正確解開返回證書中的數字簽名
服務器證書上的域名是否和服務器的實際域名相匹配
驗證通過后,將繼續進行通信,否則,終止通信
4、客戶端向服務端發送自己所能支持的對稱加密方案,供服務器端進行選擇
5、服務器端在客戶端提供的加密方案中選擇加密程度最高的加密方式。
6、服務器將選擇好的加密方案通過明文方式返回給客戶端
7、客戶端接收到服務端返回的加密方式后,使用該加密方式生成產生隨機碼,用作通信過程中對稱加密的密鑰,使用服務端返回的公鑰進行加密,將加密后的隨機碼發送至服務器
8、服務器收到客戶端返回的加密信息后,使用自己的私鑰進行解密,獲取對稱加密密鑰。 在接下來的會話中,服務器和客戶端將會使用該密碼進行對稱加密,保證通信過程中信息的安全。
libcurl庫:
libcurl是一個跨平台的網絡協議庫,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 協議。libcurl同樣支持HTTPS證書授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳,代理,cookies,和用戶認證。文檔地址https://curl.haxx.se/libcurl/c/libcurl.html
libcurl和curl命令的區別:
相同點
curl和libcurl都可以利用多種多樣的協議來傳輸文件,包括HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE等。
都支持支持SSL證書,HTTP POST, HTTP PUT,FTP上傳,基於表單的HTTP上傳,代理(proxies)、cookies、用戶名/密碼認證(Basic, Digest, NTLM等)、下載文件斷點續傳,上載文件斷點續傳(file transfer resume),http代理服務器管道(proxy tunneling)等
不同點
curl是命令行工具,可以通過shell或腳本來運行curl。curl底層所使用的庫是libcurl。
libcurl是一個庫,通常與別的程序綁定在一起使用,如命令行工具curl就是封裝了libcurl庫。所以我們也可以在你自己的程序或項目中使用libcurl以獲得類似CURL的強大功能。
實例:
1獲取

#include <stdio.h> #include <curl/curl.h> #include <stdlib.h> int main(int argc, char *argv[]) { CURL *curl; //定義CURL類型的指針 CURLcode res; //定義CURLcode類型的變量,保存返回狀態碼 if(argc!=2) { printf("Usage : file <url>;\n"); exit(1); } curl = curl_easy_init(); //初始化一個CURL類型的指針 if(curl!=NULL) { //設置curl選項. 其中CURLOPT_URL是讓用戶指 定url. argv[1]中存放的命令行傳進來的網址 curl_easy_setopt(curl, CURLOPT_URL, argv[1]); //調用curl_easy_perform 執行我們的設置.並進行相關的操作. 在這 里只在屏幕上顯示出來. res = curl_easy_perform(curl); //清除curl操作. curl_easy_cleanup(curl); } return 0; }
編譯:
gcc http1.c -o http1 –lcurl
執行:
./http1 www.baidu.com
本例只引入了libcurl的函數庫,
調用curl_global_init()初始化libcurl
調用curl_easy_init()函數得到 easy interface型指針
調用curl_easy_setopt()設置傳輸選項
根據curl_easy_setopt()設置的傳輸選項,實現回調函數以完成用戶特定任務
調用curl_easy_perform()函數完成傳輸任務
調用curl_easy_cleanup()釋放內存
在整個過程中設置curl_easy_setopt()參數是最關鍵的,幾乎所有的libcurl程序都要使用它。
實例2:進行ssl驗證

/* <DESC> * 一個簡單的https get ,輸出網頁並驗證 * </DESC> */ #include <stdio.h> #include <stdlib.h> #include <curl/curl.h> int main(int argc, char *argv[]) { CURL *curl; //定義CURL類型的指針 CURLcode res; //定義CURLcode類型的變量,保存返回狀態碼 /* if(argc!=2) { printf("Usage : file <url>;\n"); exit(1); } */ //初始化SSL and Win32運行環境 curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); //初始化一個CURL類型的指針 if(curl!=NULL) { //設置curl選項. 其中CURLOPT_URL是讓用戶指 定url. argv[1]中存放的命令行傳進來的網址 curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com"); //curl_easy_setopt(curl, CURLOPT_URL, argv[1]); //用第三方機構頒發的CA證書解密服務器端返回的證書並驗證合法性,默認1L開啟檢查,0L忽略檢查 curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L); //驗證返回的證書是否與請求的域名相同,避免被篡改證書文件,默認值2L,0L忽略檢查 curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,2L); //curl_easy_setopt(curl,CURLOPT_CAPATH,ca_path);//ca證書路徑 curl_easy_setopt(curl,CURLOPT_CAINFO,"cacert.pem");//curl官網下載的根證書 //設置curl選項,其中CURLOPT_VERBOSE是顯示執行過程中的調試信息 輸出到控制台 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //不顯示進度,如果設置為0L,則顯示處理的進度條 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); //調用curl_easy_perform 執行我們的設置.並進行相關的操作. 在這 里只在屏幕上顯示出來. res = curl_easy_perform(curl); //檢查錯誤信息輸出到控制台 if(res!=CURLE_OK){ fprintf(stderr,"curl_easy_perfrom() failed:%s\n",curl_easy_strerror(res)); } //清除curl操作. curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
(1)到 curl 官網下載證書
curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem
(2)在你的程序中設置證書的路徑
// 不檢查證書 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
// SSL CA證書
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); // 驗證服務器證書有效性
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); // 檢驗證書中的主機名和你訪問的主機名是否一致
curl_easy_setopt(curl, CURLOPT_CAPATH, "./lib/"); // 設置證書路徑
//curl_easy_setopt(curl, CURLOPT_CAINFO, "./lib/cacert.pem"); // 具體的 CA 證書,和上一行效果一樣,選用一個即可
(1)使用 PATH 或 INFO 設置路徑前要用curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);開啟驗證證書功能
(2)使用curl_easy_setopt(curl, CURLOPT_CAPATH, "./lib/");設置證書路徑
或使用curl_easy_setopt(curl, CURLOPT_CAINFO, "./lib/cacert.pem");設置具體的 CA 證書
