由於目前愈來愈多的網站或者app已經全面接入HTTPS,APPLE官方也建議APP全面使用HTTPS,況且國內這種節操都沒有喜歡劫持網絡請求的運營商在,沒有HTTPS 實在是毀用戶體驗。多數人都是隻知道HTTPS是基於HTTP的,有加密功能,但不知道這個是怎麼實現的,相信我,做爲一個開發者你之後始終會碰到HTTPS的相關問題,從源頭弄懂這份協議頗有必要。git
最好對HTTP協議有所瞭解,不須要太透徹,可是基本概念要知道。若是能懂一些TCP/IP 方面的東西就更好了。github
本文能讓還對HTTPS懵懵懂懂的你,完全從頭至尾明白這份協議究竟是怎麼一回事。太多的相關文章只告訴了你這份協議怎麼作, 卻沒告訴你爲何要這麼作,以及驗證這份協議究竟是不是真的這麼作的一個探索的過程。算法
還不知道TCP三次握手的同窗,能夠先自行搜索一下相關知識。這裏爲何要複習tcp三次握手,由於HTTP連接是在這之上的, 任何一個http連接,都須要tcp的三次握手的過程,https下面的加密層其實和這個有殊途同歸之妙。何況經過此次複習,咱們還能學習下wireshark的相關知識。掌握wireshark對咱們弄懂HTTPS相當重要。 簡單貼一下,tcp 三次握手的流程:chrome
到這裏,相信有基礎的同窗應該都回憶起來這是怎麼回事了。我不作過多解釋,直接上工具wireshark。 咱們隨便輸入一個http的地址(注意不要訪問https的,有些網站好比bat這種大網站你輸入http也會直接轉成https因此咱們仍是 隨便選個小網站確保是http的)瀏覽器
而後明顯能看出來是吧,有三次tcp的過程,而後纔是http的連接。安全
細緻分析下這個三次握手的過程:服務器
第一次握手:主機A發送位碼爲syn=1,隨機產生seq number=0的數據包到服務器,主機B由SYN=1知道,A要求創建聯機;cookie
第二次握手:主機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則鏈接創建成功。session
完成三次握手,主機A與主機B開始傳送數據。
有的人可能會問,seq number不是隨機number嗎,你這裏怎麼都是0啊。
點開詳細:
這裏面告訴你了 是相對數字,方便你看。你固然能夠選擇看實際數字 加深理解
在這個裏面把相對數字選項勾選掉,就能夠看到真實的seq number了
怎麼樣這裏是否是就豁然開朗了,固然明白就好,平時最好仍是勾選這個選項這樣理解的快一點。
這也是理解https的重要基礎之一。這裏涉及到不少複雜的算法,我並不精通算法和密碼學,因此這裏不講的太細。大家只要知道個大概便可:
對稱加密:加密和解密都用一個密鑰,有點是速度快。缺點嗎,顯而易見的是 雙方要用這個通訊的話 必須得把密鑰告知對方, 可是這個密鑰一旦被截獲了,就能夠隨便decode出來明文。實際上不夠安全。
非對稱加密:有一對密鑰,即有公鑰也有私鑰。公鑰隨便發,私鑰不會發出去 各自保管。用一個加密的話,解密就只能用另一個。好比你向銀行請求一個公鑰,銀行把公鑰發給你,你用公鑰加密一條信息之後 再發給銀行,而後銀行用私鑰解密信息。這個過程就算有人拿到公鑰,可是由於非對稱加密用一個加密 只能用另一個解密,因此 拿到這公鑰也沒用,由於沒法使用公鑰解密,能解密的私鑰還在銀行那裏,銀行固然不會傳出去,因此非對稱加密很安全。 可是這種非對稱加密很是消耗資源,速度極慢,因此要有限使用。不能無節制使用。
HASH加密算法:這個就好像MD5這樣的加密方式,是不可逆的。
這個很好理解是吧,敏感信息確定要加密的,明文傳輸等於自殺。不過多解釋了。
這個不少人不理解,這是啥意思,按道理說咱們用非對稱加密應該就完美了啊。可是謹記咱們的數據包不是從A直接到B的。 中間要通過無數次的路由器轉發等等,這個中間一旦有人截獲了咱們的數據包,換成本身的數據包,就很危險了。 因此咱們還須要一種機制能校驗通信雙方的身份。確保我是在和我老婆說話 而不是在我和丈母孃說話。
這個也不是很容易理解,按道理說TCP是能保證數據有序完整的到達對方的。可是不要忘記中間咱們通過的無數次路由器轉發, 可能被劫持,被劫持之後可能會對數據包進行篡改,這個時候咱們須要一種機制保護咱們的數據不被篡改,即便被篡改 也能被咱們察覺,確保我對我老婆寫的信能完整的讓我老婆看到,而不是隻看到一半。
根據前面咱們闡述的加密算法和安全通訊三原則,爲了保證咱們的通訊可以安全進行,能夠試想出一種流程來保證通訊安全:
目前來看,這個思路是否是很完美。公鑰即便被中間人截獲之後也沒用,由於拿到公鑰也解密不出來到底雙方是用哪一種算法加密的。 但有個重大缺陷:
中間人能夠將服務器發送的公鑰包進行掉包,客戶端怎麼知道這個公鑰是真的服務器發送的仍是假的中間人給的非法公鑰呢?
能夠看這張圖,基本上中間人攻擊就是這個圖所示的意思。
這個問題的解決辦法其實也很粗暴:
帶來的問題:
客戶端到哪去取第三方公鑰?
你的操做系統或者瀏覽器自身就帶有權威機構的第三方公鑰
若是中間人獲得CA認證怎麼辦?這種狀況基本沒辦法處理,若是發生,那麼這個CA下面全部的證書都被認爲非法了。因此 CA審覈也很嚴格啊
能夠本身製做證書,而後把這個證書的公鑰放在客戶端(例如app的安裝目錄下),這樣app只要使用本身的證書公鑰便可 解密了,不須要使用系統的。可是這樣帶來的問題是,若是有人獲取到了你這個公鑰證書咋辦? 數字簽名認證算法便可保證此類問題,其實簡單來講就是服務器和客戶端事先約定好一種加密規則便可,就能夠得知是否被篡改。 這部分因爲不是重點,暫時不講的太細,只要知道有這麼個事便可。實際上你弄懂整個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的加密 層也能獲知,避免發生事故。
目標訪問地址就用github吧。 抓出來是這樣的。
注意看tlsv1的就能夠了這個就是加密層。
下面就來逐步分析
注意到這裏服務器和客戶端就有2個隨機數了。而且加密算法也肯定了。
這部分主要是發送證書信息的 點開之後 證書的詳細信息都能看到 另外serverhellodone的意思就是服務器的工做都完畢了。
能夠看出來這裏一共有三個步驟,咱們來依次分析 這三次動做都作了什麼
Client Key Exchange
服務器收到這個random3的加密信息之後,用本身的私鑰解密,這樣服務器和客戶端就共同擁有了random 123 3組隨機數,而後用這三組數據生成一個密鑰,這個密鑰就是後面咱們applicationdata交互時使用的對稱加密的密鑰了
這個session ticket就是服務器最後一步的時候傳給客戶端的一個數據。 這個加密數據客戶端收到之後就能夠保存下來,這樣下一次再請求https的 時候,就能夠把這個session ticket發過去,這樣能夠省不少握手的時間和 資源消耗。(前面咱們分析的4-5步其實已經至關複雜了,尤爲是非對稱加密對服務端的資源消耗至關之大)
實際上對於多數瀏覽器來講,指向同一個域名的https鏈接,咱們都會有意識的讓第一個https鏈接完成握手以後再鏈接第n個 https。由於這樣 後續的https 就能夠攜帶相關信息,能夠省不少資源
這個ticket實際上就有點相似cookie。
在筆者的此次訪問chrome-gitub的過程當中,瀏覽器並無使用ticket技術 而是使用的seession id技術:
sessionid 實際上做用和ticket差很少,可是sessionid 沒法作到服務器之間同步,畢竟id 存在服務器內存中,負載均衡帶來的狀態機同步是一個大問題。
其實HTTPS總結起來就是3次tcp握手-5次TLS握手。搞清楚每一步作什麼, 用的是對稱加密仍是非對稱加密,整個流程就確定能搞清楚了。 之後遇到相似的問題就能快速定位優化了。甚至抓取BAT的HTTPS接口 數據都不是難事。若是有須要的話你們就在下方留言,我會盡快 教你們如何抓取bat的https接口數據 而且decode出明文。