深入理解HTTPS協議

DK_BurNIng發表於2017-12-19

為什麼需要深入理解HTTPS協議

因為目前越來越多的網站或者app已經全面接入HTTPS,APPLE官方也建議APP全面使用HTTPS,何況國內這種節操都沒有喜歡劫持網路請求的運營商在,沒有HTTPS 實在是毀使用者體驗。多數人都是隻知道HTTPS是基於HTTP的,有加密功能,但不知道這個是怎麼實現的,相信我,作為一個開發者你以後始終會碰到HTTPS的相關問題,從源頭弄懂這份協議很有必要。

閱讀本文需要什麼基礎

最好對HTTP協議有所瞭解,不需要太透徹,但是基本概念要知道。如果能懂一些TCP/IP 方面的東西就更好了。

閱讀本文能有什麼好處

本文能讓還對HTTPS懵懵懂懂的你,徹底從頭到尾明白這份協議到底是怎麼一回事。太多的相關文章只告訴了你這份協議怎麼做, 卻沒告訴你為什麼要這麼做,以及驗證這份協議到底是不是真的這麼做的一個探索的過程。

從Wireshark複習TCP三次握手的重要性

還不知道TCP三次握手的同學,可以先自行搜尋一下相關知識。這裡為什麼要複習tcp三次握手,因為HTTP連結是在這之上的, 任何一個http連結,都需要tcp的三次握手的過程,https下面的加密層其實和這個有異曲同工之妙。況且通過這次複習,我們還能學習下wireshark的相關知識。掌握wireshark對我們弄懂HTTPS至關重要。 簡單貼一下,tcp 三次握手的流程:

深入理解HTTPS協議

深入理解HTTPS協議

到這裡,相信有基礎的同學應該都回憶起來這是怎麼回事了。我不做過多解釋,直接上工具wireshark。 我們隨便輸入一個http的地址(注意不要訪問https的,有些網站比如bat這種大網站你輸入http也會直接轉成https所以我們還是 隨便選個小網站確保是http的)

深入理解HTTPS協議

然後明顯能看出來是吧,有三次tcp的過程,然後才是http的連結。

細緻分析下這個三次握手的過程:

第一次握手:主機A傳送位碼為syn=1,隨機產生seq number=0的資料包到伺服器,主機B由SYN=1知道,A要求建立聯機;

第二次握手:主機B收到請求後要確認聯機資訊,向A傳送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=0的包

第三次握手:主機A收到後檢查ack number是否正確,即第一次傳送的seq number+1,以及位碼ack是否為1,若正確,主機A會再傳送ack number=(主機B的seq+1),ack=1,主機B收到後確認seq值與ack=1則連線建立成功。

完成三次握手,主機A與主機B開始傳送資料。

有的人可能會問,seq number不是隨機number嗎,你這裡怎麼都是0啊。

點開詳細:

深入理解HTTPS協議

這裡面告訴你了 是相對數字,方便你看。你當然可以選擇看實際數字 加深理解

深入理解HTTPS協議

在這個裡面把相對數字選項勾選掉,就可以看到真實的seq number了

深入理解HTTPS協議

怎麼樣這裡是不是就豁然開朗了,當然明白就好,平時最好還是勾選這個選項這樣理解的快一點。

對稱加密和非對稱加密

這也是理解https的重要基礎之一。這裡涉及到很多複雜的演算法,我並不精通演算法和密碼學,所以這裡不講的太細。你們只要知道個大概即可:

對稱加密:加密和解密都用一個金鑰,有點是速度快。缺點嗎,顯而易見的是 雙方要用這個通訊的話 必須得把金鑰告知對方, 但是這個金鑰一旦被截獲了,就可以隨便decode出來明文。實際上不夠安全。

非對稱加密:有一對金鑰,即有公鑰也有私鑰。公鑰隨便發,私鑰不會發出去 各自保管。用一個加密的話,解密就只能用另外一個。比如你向銀行請求一個公鑰,銀行把公鑰發給你,你用公鑰加密一條資訊以後 再發給銀行,然後銀行用私鑰解密資訊。這個過程就算有人拿到公鑰,但是因為非對稱加密用一個加密 只能用另外一個解密,所以 拿到這公鑰也沒用,因為無法使用公鑰解密,能解密的私鑰還在銀行那裡,銀行當然不會傳出去,所以非對稱加密很安全。 但是這種非對稱加密非常消耗資源,速度極慢,所以要有限使用。不能無節制使用。

HASH加密演算法:這個就好像MD5這樣的加密方式,是不可逆的。

確保安全通訊的三個原則

A.資料內容的加密

這個很好理解是吧,敏感資訊肯定要加密的,明文傳輸等於自殺。不過多解釋了。

B.通訊雙方的身份校驗

這個很多人不理解,這是啥意思,按道理說我們用非對稱加密應該就完美了啊。但是謹記我們的資料包不是從A直接到B的。 中間要經過無數次的路由器轉發等等,這個中間一旦有人截獲了我們的資料包,換成自己的資料包,就很危險了。 所以我們還需要一種機制能校驗通訊雙方的身份。確保我是在和我老婆說話 而不是在我和丈母孃說話。

C.資料內容的完整性

這個也不是很容易理解,按道理說TCP是能保證資料有序完整的到達對方的。但是不要忘記中間我們經過的無數次路由器轉發, 可能被劫持,被劫持以後可能會對資料包進行篡改,這個時候我們需要一種機制保護我們的資料不被篡改,即使被篡改 也能被我們察覺,確保我對我老婆寫的信能完整的讓我老婆看到,而不是隻看到一半。

https的設計思路

根據前面我們闡述的加密演算法和安全通訊三原則,為了保證我們的通訊能夠安全進行,可以試想出一種流程來保證通訊安全:

  • 伺服器為每個客戶端生成一個公鑰,將公鑰傳送給客戶端
  • 客戶端選擇一個加密演算法,然後用公鑰加密以後傳送給伺服器
  • 伺服器收到這個公鑰加密後的演算法以後拿自己的私鑰解密,然後就知道這個加密演算法是哪個了。今後就一直用這個演算法通訊。

目前來看,這個思路是不是很完美。公鑰即使被中間人截獲以後也沒用,因為拿到公鑰也解密不出來到底雙方是用哪種演算法加密的。 但有個重大缺陷:

中間人可以將伺服器傳送的公鑰包進行掉包,客戶端怎麼知道這個公鑰是真的伺服器傳送的還是假的中間人給的非法公鑰呢?

可以看這張圖,基本上中間人攻擊就是這個圖所示的意思。

深入理解HTTPS協議

解決中間人攻擊問題

這個問題的解決辦法其實也很粗暴:

  • 使用權威的第三方機構也就是CA向安全的伺服器頒發證書。來證明這臺伺服器的合法性。
  • 伺服器通過這個證書來把自己的公鑰加密以後發給客戶端
  • 客戶端收到這個加密後的公鑰以後 ,就用第三方機構的公鑰 把這個伺服器返回的加密後的公鑰 解密 從而得到真正的伺服器 的公鑰

帶來的問題:

客戶端到哪去取第三方公鑰?

  • 你的作業系統或者瀏覽器自身就帶有權威機構的第三方公鑰

  • 如果中間人得到CA認證怎麼辦?這種情況基本沒辦法處理,如果發生,那麼這個CA下面所有的證書都被認為非法了。所以 CA稽核也很嚴格啊

CA證書是收費的啊,我不想交錢咋辦呢

可以自己製作證書,然後把這個證書的公鑰放在客戶端(例如app的安裝目錄下),這樣app只要使用自己的證書公鑰即可 解密了,不需要使用系統的。但是這樣帶來的問題是,如果有人獲取到了你這個公鑰證書咋辦? 數字簽名認證演算法即可保證此類問題,其實簡單來說就是伺服器和客戶端事先約定好一種加密規則即可,就可以得知是否被篡改。 這部分由於不是重點,暫時不講的太細,只要知道有這麼個事即可。實際上你弄懂整個https以後這個地方就自然而然也能 想明白了。

有了上述基礎,我們終於可以按照科班的方式來理解HTTPS真正的流程

為什麼HTTPS的流程要放在最後再講,因為放在前面講,根本不會理解為啥要這麼做,很快就會忘記。有了前面的基礎 再來看這個流程,就會恍然大悟。

深入理解HTTPS協議

  • 先看藍色的部分,可以看出來,這是tcp連結。所以https的加密層也是在tcp之上的。

  • 客戶端首先發起clientHello訊息。包含一個客戶端隨機生成的random1 數字,客戶端支援的加密演算法,以及SSL資訊。

  • 伺服器收到客戶端的clientHello訊息以後,取出客戶端法發來的random1數字,並且取出客戶端發來的支援的加密演算法, 然後選出一個加密演算法,並生成一個隨機數random2,傳送給客戶端serverhello

  • 讓客戶端對伺服器進行身份校驗,服務端通過將自己的公鑰通過數字證書的方式傳送給客戶端

  • 客戶端收到服務端傳來的證書後,先從 CA 驗證該證書的合法性,驗證通過後取出證書中的服務端公鑰,再生成一個隨機數 Random3,再用服務端公鑰非對稱加密 Random3 生成 PreMaster Key。並將PreMaster Key傳送到服務端,服務端通過私鑰將PreMaster Key解密獲取到Random3,此時客戶端和伺服器都持有三個隨機數Random1 Random2 Random3,雙方在通過這三個隨即書生成一個對稱加密的金鑰.雙方根據這三個隨即數經過相同的演算法生成一個金鑰,而以後應用層傳輸的資料都使用這套金鑰進行加密.

  • Change Cipher Spec:告訴客戶端以後的通訊都使用這一套金鑰來進行.

最後ApplicationData 全部使用對稱加密的原因就是非對稱加密太卡,對稱加密不影響效能。所以實際上也看的出來 HTTPS的真正目的就是保證對稱加密的 金鑰不被破解,不被替換,不被中間人攻擊,如果發生了上述情況,那麼HTTPS的加密 層也能獲知,避免發生事故。

最後我們用WireShark再來還原一次HTTPS的互動過程把

目標訪問地址就用github吧。 抓出來是這樣的。

深入理解HTTPS協議

注意看tlsv1的就可以了這個就是加密層。

下面就來逐步分析

  • ClientHello

深入理解HTTPS協議

  • severHello

深入理解HTTPS協議

注意到這裡伺服器和客戶端就有2個隨機數了。並且加密演算法也確定了。

  • severHelloDone

深入理解HTTPS協議

這部分主要是傳送證書資訊的 點開以後 證書的詳細資訊都能看到 另外serverhellodone的意思就是伺服器的工作都完畢了。

深入理解HTTPS協議

  • 來看看第四步,客戶端-->服務端 到底做了什麼

深入理解HTTPS協議

可以看出來這裡一共有三個步驟,我們來依次分析 這三次動作都做了什麼

Client Key Exchange

深入理解HTTPS協議

伺服器收到這個random3的加密資訊以後,用自己的私鑰解密,這樣伺服器和客戶端就共同擁有了random 123 3組隨機數,然後用這三組資料生成一個金鑰,這個金鑰就是後面我們applicationdata互動時使用的對稱加密的金鑰了

  • 第五步 服務端-客戶端

深入理解HTTPS協議

  • 最後看看第六步也是最後一步,傳輸資料層。
    深入理解HTTPS協議

new session ticket是啥意思

深入理解HTTPS協議

這個session ticket就是伺服器最後一步的時候傳給客戶端的一個資料。 這個加密資料客戶端收到以後就可以儲存下來,這樣下一次再請求https的 時候,就可以把這個session ticket發過去,這樣可以省很多握手的時間和 資源消耗。(前面我們分析的4-5步其實已經相當複雜了,尤其是非對稱加密對服務端的資源消耗相當之大)

實際上對於多數瀏覽器來說,指向同一個域名的https連線,我們都會有意識的讓第一個https連線完成握手之後再連線第n個 https。因為這樣 後續的https 就可以攜帶相關資訊,可以省很多資源

這個ticket實際上就有點類似cookie。

在筆者的這次訪問chrome-gitub的過程中,瀏覽器並沒有使用ticket技術 而是使用的seession id技術:

深入理解HTTPS協議

sessionid 實際上作用和ticket差不多,但是sessionid 無法做到伺服器之間同步,畢竟id 存在伺服器記憶體中,負載均衡帶來的狀態機同步是一個大問題。

總結

其實HTTPS總結起來就是3次tcp握手-5次TLS握手。搞清楚每一步做什麼, 用的是對稱加密還是非對稱加密,整個流程就肯定能搞清楚了。 以後遇到類似的問題就能快速定位優化了。甚至抓取BAT的HTTPS介面 資料都不是難事。如果有需要的話大家就在下方留言,我會盡快 教大家如何抓取bat的https介面資料 並且decode出明文。

相關文章