使用curl,libcurl訪問Https

編譯curl,libcurl

下載curl源碼(git clone https://github.com/curl/curl),在目錄curl\winbuild\BUILD.WINDOWS.txt文件中,詳細介紹了使用nmake編譯windows下curl及libcurl庫的相關命令,摘錄以下:php

nmake /f Makefile.vc mode=<static or dll> <options>

where <options> is one or many of:
  VC=<6,7,8,9,10,11,12,14>     - VC versions
  WITH_DEVEL=<path>            - Paths for the development files (SSL, zlib, etc.)
                                 Defaults to sibbling directory deps: ../deps
                                 Libraries can be fetched at http://windows.php.net/downloads/php-sdk/deps/
                                 Uncompress them into the deps folder.
  WITH_SSL=<dll or static>     - Enable OpenSSL support, DLL or static
  WITH_MBEDTLS=<dll or static> - Enable mbedTLS support, DLL or static
  WITH_CARES=<dll or static>   - Enable c-ares support, DLL or static
  WITH_ZLIB=<dll or static>    - Enable zlib support, DLL or static
  WITH_SSH2=<dll or static>    - Enable libSSH2 support, DLL or static
  ENABLE_SSPI=<yes or no>      - Enable SSPI support, defaults to yes
  ENABLE_IPV6=<yes or no>      - Enable IPv6, defaults to yes
  ENABLE_IDN=<yes or no>       - Enable use of Windows IDN APIs, defaults to yes
                                 Requires Windows Vista or later, or installation from:
                                 https://www.microsoft.com/downloads/details.aspx?FamilyID=AD6158D7-DDBA-416A-9109-07607425A815
  ENABLE_WINSSL=<yes or no>    - Enable native Windows SSL support, defaults to yes
  GEN_PDB=<yes or no>          - Generate Program Database (debug symbols for release build)
  DEBUG=<yes or no>            - Debug builds
  MACHINE=<x86 or x64>         - Target architecture (default is x86)

  由編譯命令可知,編譯curl主要有兩種ssl模式,默認是基於windows的winssl編譯,另外一種是基於openssl加密庫。html

1、curl+winsslgit

命令:github

nmake /f Makefile.vc mode=dll vc=10 

這時默認使用SSPI、IDN、WINSSL等技術,編譯後使用windows系統自帶的CA數字證書文件、ssl加密庫winssl(Schannel and Secure Transport),這種編譯方式有不少優勢,一是由於使用windows自帶的加密庫,沒有跨平臺等考慮因素,性能天然是最優的;二是不用引入第三方庫openssl,也不須要顯示設置https CA數字證書文件或者打包根證書到軟件中。可是缺點也是很明顯的,由於windows有不少系統版本,不一樣版本的ssl有較大區別,早期windows上的ssl安全性能沒那麼高;最嚴重的一個問題是,windows xp及如下系統在國內用戶量仍是很大的,而windows xp不支持SNI技術,若是服務器使用了SNI技術,並且同一個域名配置了多個證書,有可能致使返回證書錯誤,致使https訪問失敗。
算法

SNI:Server Name Indication,是爲了應對虛擬服務器技術的興起而產生的,就是容許同一臺服務器佈置多個域名,在發起https請求的時候,會將請求的域名加到https請求頭中,服務端收到請求後,根據請求頭中的域名返回對應的根證書。windows

2、curl+opensslapi

命令:安全

nmake /f Makefile.vc mode=dll VC=10 WITH_DEVEL=OpenSLL編譯目錄 ENABLE_SSPI=no ENABLE_WINSSL=no

這種編譯方式,首先得下載OpenSSL源碼或者已經編譯好的OpenSSL庫,放到指定目錄並設置到參數WITH_DEVEL參數中,具體的編譯方式可參考http://www.cnblogs.com/openiris/p/3812443.html
服務器

基於OpenSSL編譯的curl和libcurl,一大優勢是使用的較新的SSL加密算法, 安全性較高,並且不須要考慮不一樣的操做系統SSL庫不一樣致使的各類問題;缺點就是須要單獨引入OpenSSL庫,須要手動從Mozilla導出根證書,編譯到OpenSSL或者打包到軟件中,在curl中顯示設置加載。 curl官網提供CA數字證書文件下載,地址是https://curl.haxx.se/ca/cacert.pem,更新地址是https://curl.haxx.se/docs/caextract.html 。app

 遠程更新CA數字證書命令(證書發生改變了纔會下載):

curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem

 

查看 CURL和LIBCURL版本/SSL/支持協議/特性

使用curl -V能夠查看編譯好的libcurl庫支持的功能,以及支持的ssl庫:

libcurl+winssl編譯:

libcurl+openssl編譯:

CURL HTTPS參數含義

1、CURL_VERIFY_PEER

該參數含義是驗證HTTPS請求對象的合法性,就是用第三方證書機構頒發的CA數字證書來解密服務端返回的證書,來驗證其合法性。可在編譯時就將CA數字證書編譯進去,也能夠經過參數CURLOPT_CAINFO 或者CURLOPT_CAPATH設置根證書。默認值爲1。

2、CURL_VERIFY_HOST

該參數主要用於https請求時返回的證書是否與請求的域名相符合,避免被中間着篡改證書文件。默認值爲2。

 

LIBCURL基於WinSSL和OpenSSL訪問HTTPS示例

1、忽略證書驗證

若是不想驗證PEER和HOST的安全性,能夠經過設置

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);//忽略證書檢查
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

2、LibCurl HTTPS 示例

WinSSL:

void winssl_Https()  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();      
  if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    //...
   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);//winssl編譯時使用windows自帶的根證書 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
   //...
  curl_easy_cleanup(curl); 
} 

 OpenSSL:

void openssl_https(const char * pCaPath)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();     
  if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
  //...
  if(pCaPath){
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);//openssl編譯時使用curl官網或者firefox導出的第三方根證書文件 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);/*pCaPath爲證書路徑 */
   else{     
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);      curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);      curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem");//cacert.pem爲curl官網下載的根證書文件 
  } 
  //...
  curl_easy_cleanup(curl); 
} 

  

參考資料:

a) https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html

b) https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html

c) https://curl.haxx.se/docs/sslcerts.html

相關文章
相關標籤/搜索