Https詳解

背景

隨着用戶安全意識的加強,近兩年網絡協議已逐步從Http協議向Https協議開始過分,目前大多數APP/Web都開始使用Https協議,這裏以Http逐步發展成Https協議的過程爲導向,介紹Https的誕生過程。html

HTTP協議的缺點

  • 通訊使用明文;
  • 不驗證通訊方的身份;
  • 沒法驗證報文的完整性;

通訊使用明文

通訊使用明文意味着安全性大大下降,當通訊過程被竊聽後,無需花費額外的投入就可看到傳輸的數據。例如使用抓包工具,無需任何配置就可查看任何使用HTTP協議的通訊數據;linux

不驗證通訊方身份

不驗證通訊方的身份,將致使通訊過程被竊聽後,可能會遭遇假裝,例如使用抓包工具抓取數據後,就可按照數據包的格式構造HTTP請求;算法

沒法驗證報文的完整性

不驗證報文的完整性,數據在傳輸過程當中就可能被篡改,原本想看喜洋洋呢,結果數據在傳輸過程當中被換成了光頭強。編程

解決方案

通訊使用明文

既然明文不安全,那能夠考慮使用密文,即:對通訊數據進行加密。即使數據被竊聽,對方依然須要花費必定的投入來破解,這種高昂的成本間接提升了安全級別。安全

不驗證通訊方身份

和服務端使用相同的算法,根據網絡請求參數生成一個token,請求/應答時根據token來肯定雙方的身份。服務器

沒法驗證報文的完整性

使用MD5/SHA1等算法進行完整性驗證, 對方接收到數據後,根據一樣的算法生成散列值,比對發送方生成的散列值,便可驗證數據的完整性。 解決了HTTP的以上問題,HTTPS協議就誕生了:網絡

Https = Http + 加密 + 認證 + 完整性驗證
複製代碼

而對於加密,認證和完整性驗證這些特色,TCP/IP協議族中已經提供了一個用於數據安全傳輸的協議——SSL(Secure Socket Layer)安全套接層,雖然也是基於TCP實現的,但SSL並非應用層協議,而是一個位於應用層與傳輸層之間的協議,(具體協議相關的理論知識可參考網絡編程之理論知識。)其目的就是爲上層的應用層協議提供安全的傳輸通道。這時Https協議就可用如下形式表示:併發

Https = Http + SSL
複製代碼

這樣看來,HTTPS並非一個單獨的應用層協議,而只是Http使用SSL通道進行數據傳輸的過程。那麼對於Https, 只須要了解Http(參考HTTP詳解)和SSL協議便可。而所謂的HTTPS報文也就是SSL報文: dom

SSL協議

SSL(Secure Socket Layer)安全套接層,是一種位於應用層與傳輸層之間,爲網絡通訊提供安全及完整性驗證的一種網絡協議。工具

相對於TCP或HTTP協議,SSL協議要複雜不少。因爲它也是創建在TCP協議之上的,因此在使用SSL傳輸數據以前須要先進行三次握手和服務器創建鏈接,具體的流程如圖所示:

SSL協議的握手過程

  1. 客戶端先給服務端發送一個消息,消息內容包括:客戶端支持的加密方式,支持的壓縮方法,SSL的版本號,客戶端生成的隨機數,文本內容「Hello」等;
  2. 服務端接收到消息後,也回發一個Hello,並攜帶從客戶端支持的加密方式中選擇的加密方式,服務端生成的隨機數,服務端的SSL版本號等信息;
  3. 隨後服務器給客戶端發送一個Certificate報文,報文中包含服務端的公鑰證書;
  4. 緊接着服務器給客戶端發送Server Hello Done, 表示最初的協商握手過程結束;
  5. 客戶端接收到服務端發送的握手結束的消息後,以Client Key Exchange做爲迴應,此報文中包含通訊加密過程當中使用的一種被稱爲Pre-master secret的隨機密碼串,並使用第三步接收到的公鑰證書進行了加密;
  6. 接着客戶端發送Change Cipher Spec報文,該報文告知服務端,此步驟以後的全部數據將使用第五步中生成的master secret進行加密(master secret的生成過程看後面的介紹);
  7. 隨後客戶端發送Finish報文,此報文中包含鏈接至今全部報文的總體校驗值,用於完整性驗證;
  8. 服務端接收到客戶端發送的Change Cliper Spec報文後,一樣以Change Cliper Spec報文做爲迴應;
  9. 接着服務端發送Finish報文給客戶端,表示服務端已正確解析客戶端發送的總體校驗值,至此,SSL握手的過程結束。
  10. 隨後開始使用HTTP協議傳輸使用master secret加密過的數據。
說明
  • 前兩步是協商加密算法以及傳輸各自生成的隨機數(爲後續生成master secret作準備)的過程;

  • 第三步服務端將本身的證書發送給客戶端,這個證書中包含一個數字簽名(CA簽名)和服務端CA證書的公鑰,客戶端對證書中包含的服務端信息進行Hash, 同時使用接收到的公鑰對數字證書解密,獲取其中的Hash值,與前面計算獲得的Hash值進行比較,便可驗證證書的有效性(完整性&真實性);

  • 服務端收到客戶端發送的Change Cipher Spec(第五步),會使用本身的私鑰進行解密,獲取報文中的Pre-master secret,這時通訊雙方都擁有對方的Random(前兩步生成的),Pre-master secret,以及自身的Random, 將三個數做爲種子經過算法生成master secret, 用來加密後續Http請求過程當中的數據。其中master secret的生成規則爲:

    master_secret = MD5(pre_master_secret + SHA('A' + pre_master_secret + ClientHello.random + ServerHello.random)) + MD5(pre_master_secret + SHA('BB' + pre_master_secret + ClientHello.random + ServerHello.random)) + MD5(pre_master_secret + SHA('CCC' + pre_master_secret + ClientHello.random + ServerHello.random));

更詳細的有關SSL協議的內容可參考:RFC 6101 SSL

爲何須要這麼複雜

兩個方面的考量:安全,效率。若是直接使用對稱加密的方式進行加密,若是密鑰不被泄漏固然也是安全,但問題是:密鑰如何傳遞給另外一端呢,在數據傳輸過程當中,若是通訊被竊聽,則密鑰被竊取,那此時加密就沒有任何意義了。那可不可使用非對稱加密的方式呢?理論上是能夠的,數據傳輸以前,服務端只須要將本身的公鑰傳輸給客戶端,客戶端在傳輸數據時,使用接收的公鑰進行加密,服務端接收到數據後使用私鑰進行解密便可。但這裏有個不容忽視的問題:效率。非對稱加密須要大量計算,確定會佔用不少硬件資源,因此效率過低。因此爲了解決安全和效率問題,SSL使用了對稱加密(加密和解密使用一樣的密鑰)和非對稱加密(公鑰加密,私鑰解密)組合的方式:使用非對稱加密的方式傳輸對稱加密中生成密鑰的種子(pre master secret)【對應上面的第五步】,而後使用對稱加密的方式對通訊數據進行加密【對應上面的第十步】,既保障了密鑰的安全性,也提升了加密速度。

Https真的安全麼

既然Https那麼安全,那爲何用抓包工具仍是能夠看到裏面的數據。這裏須要對抓包過程的原理作一個簡單的介紹,抓包,其實就是中間人攻擊,在網絡請求過程當中,抓包工具充當着客戶端/服務端的角色,當客戶端請求數據時,抓包工具將請求進行攔截,而後構造數據(冒充客戶端)向服務端發起請求,此時服務端會返回本身的公鑰證書,而後抓包工具將服務端的公鑰證書替換成本身的公鑰證書,隨後將數據返回可客戶端(此時充當服務端的角色)。客戶端拿到公鑰證書後,使用公鑰證書中的公鑰對Pre-master secret進行加密,併發送給服務端,發送過程當中又被抓包工具攔截,因爲客戶端使用的公鑰其實就是抓包工具生成的證書公鑰,因此抓包工具只須要使用本身的私鑰進行解密便可拿到真實的Pre-master secret(由於抓包工具在以前的過程當中已經拿到了雙方的隨機碼,因此到這一步抓包工具至關於已經拿到了後續通訊使用的密鑰),隨後抓包工具使用從服務端接收到的公鑰證書中的公鑰對Pre-master secret進行加密,而後發送給服務端。隨後的通訊過程雖然進行了加密,但抓包工具已經生成了密鑰(master secret),因此能夠查看Https的通訊內容。一圖以蔽之:

image

從抓包的原理能夠看出,對Https進行抓包,須要PC端和手機端同時安裝證書。

既然這麼容易被抓包,那Https會不會顯得很雞肋?其實並不會,能抓包,那是由於你信任抓包工具,手機上安裝了與之對應的證書,你要不安裝證書,你抓一個試試。並且安全這個課題,是在攻防中求發展,沒有最安全,只有更安全,因此將攻擊的成本提升了,就間接達到了安全的目標。

如何對Https進行抓包

這裏以Charles4.0爲例,對Https進行抓包:

  1. 依次點擊菜單Help -> SSL Proxying -> Install Charles Root Certificate安裝PC證書;
  2. 依次點擊菜單Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device or Romote Browser, 此時會彈出一個框,提示讓你去 chls.pro/ssl 去下載證書,下載完成後進行安裝便可;
  3. 依次點擊菜單Proxy -> SSL Proxying Settings, 選中頁面中的Enable SSL Proxying, 而後點擊下面的add, 在彈出的框中的Host編輯框中填寫*.* (表示可對全部Https請求進行抓包),端口填寫443,點擊OK;
  4. 手機設置代理(你的電腦的IP地址,端口默認爲8888)便可進行抓包;

如何避免被抓包

既然使用了Https協議,就是不想讓別人看到數據,那如何避免被抓包呢?這裏有2種方法可參考:

  • 使用自定義協議;
  • 使用SSL Pinning;

使用TCP協議

使用自定義協議,也就是以TCP/UDP爲基礎,使用Socket進行通訊(具體可參考網絡編程之理論篇),這種方式因爲不是使用的Http/Https協議,因此可避免Http類型的抓包工具(如Charles, Fiddler)進行抓包, 但不可避免WireShark,畢竟它太強大,可抓取網絡模型中各層的數據。

使用SSL Pinning

看着很陌生,其實也不是啥新技術,只須要將服務端的公鑰證書一塊兒打到APK中,在網絡請求時,與服務端的公鑰證書進行比較,便可避免抓包工具使用構造證書進行抓包的狀況。

總結

以上即是整個Http過渡到Https的過程,這種以協議發展爲導向的方式,可能更有助於理解。固然,這只是我的對Https協議的理解,若有不恰當之處,歡迎指正。

參考書籍/文章

圖解HTTP

SSL/TLS原理詳解

相關文章
相關標籤/搜索