《大前端進階 安全》系列 HTTPS詳解(文末掘金證書分析)

前言

Coding 應當是一輩子的事業,而不只僅是 30 歲的青春🍚
本文已收錄 GitHub https://github.com/ponkans/F2E,歡迎 Star,持續更新💧前端

網上不少文章對 HTTPS 的講解雲裏霧裏,看完這篇,若是還不理解,你直接加怪怪微信,罵我渣男好了(不少細節請教了螞蟻金服作安全的朋友)~git

整個 HTTPS 的演變跟流程細思極恐,有不少思想能夠借鑑學習。我之後要離搞安全的朋友遠一點github


每篇文章都但願你能收穫到東西,這篇將帶你深刻 HTTPS 加解密原理,但願看完可以有這些收穫:算法

  • 明白 HTTPS 到底解決了什麼問題
  • 理解對稱加密與非對稱加密的原理和使用場景
  • 明白 CA 機構和根證書到底起了什麼做用

Why HTTPS

近幾年來,各大公司都在大力推動 HTTPS 的建設。Google Chrome將非 HTTPS 的網站標註爲「不安全」,蘋果要求 APP 中須要使用HTTPS進行通訊,微信小程序也要求使用HTTPS協議。那麼,咱們爲何非要作這麼一件事呢?小程序

咱們先來看看HTTP。HTTP(Hypertext Transfer Protocol)超文本傳輸協議,是一種用於分佈式、協做式和超媒體信息系統的應用層協議,能夠說 HTTP 是當代互聯網通訊的基礎。微信小程序

可是,HTTP 有着一個致命的缺陷,那就是內容是明文傳輸的,沒有通過任何加密,而這些明文數據會通過WiFi、路由器、運營商、機房等多個物理設備節點,若是在這中間任意一個節點被監聽,傳輸的內容就會徹底暴露,,這一攻擊手法叫作MITM(Man In The Middle)中間人攻擊。api

舉個例子,稍微有點長,但這個例子透露出了怪怪我對安全如此癡迷的緣由~~

能夠拿小時候上課傳紙條來類比,你坐在教室靠牆的一邊,想要傳一句「晚上放學操場我等你」給坐在窗邊的小紅,中間要通過六七我的的傳遞。雖然你把紙條對摺了一下,可是防君子不防小人,中間的全部人均可以很輕易地打開紙條看到你想要說什麼。瀏覽器

只是看還好,若是有小剛也喜歡小紅,看到你倆立刻就要甜甜蜜蜜地回家了,心有不甘,換了一張紙條,改爲了「晚上放學你本身回家吧,我要去網吧玩遊戲」安全

小紅看到你要拋棄她本身去玩遊戲,很是傷心,開始在紙條上質問「說好的一塊兒回家呢,爲何要去打遊戲,哼」微信

在小紅的紙條傳回來的路上,小剛又改了紙條「你玩你的遊戲去吧,我要和小剛回家」

因而,你和小紅都倍感傷心,小剛橫刀奪愛,而你一頭霧水。


回憶一下幾年前遍地都是的運營商劫持,當你訪問一個原本很正常的網頁,但頁面上卻莫名其妙出現了一些廣告標籤、跳轉腳本、欺騙性的紅包按鈕,甚至有時候原本要下載一個文件,最後下下來卻變成了另一個徹底不一樣的東西,這些都是被運營商劫持了HTTP明文數據的現象。

運營商劫持
運營商劫持

還有各大公司的員工安全培訓裏都有一條「不要連陌生的WiFi」,也是相似的緣由,惡意WiFi的控制者能夠看到和篡改HTTP明文傳輸的信息。

爲了解決HTTP明文傳輸數據可能致使的安全問題,1994年網景公司提出了HTTPS(HyperText Transfer Protocol Secure)超文本傳輸安全協議,數據通訊仍然是HTTP,但利用SSL/TLS加密數據包

HTTPS實現原理

前面說到,HTTPS其實就是將HTTP的數據包再經過SSL/TLS加密後傳輸,那麼SSL/TLS又是什麼呢?

SSL(Secure Sockets Layer)安全套接層和TLS(Transport Layer Security)傳輸層安全協議實際上是一套東西

網景公司在1994年提出HTTPS協議時,使用的是SSL進行加密。後來IETF(Internet Engineering Task Force)互聯網工程任務組將SSL進一步標準化,於1999年公佈初版TLS協議文件TLS 1.0。目前最新版的TLS協議是TLS 1.3,於2018年公佈。

工做流程

咱們先來看看HTTPS的加解密流程。

HTTPS加解密流程
HTTPS加解密流程
  1. 用戶在瀏覽器發起HTTPS請求(如 juejin.im/),默認使用服務端的443端口進行鏈接;
  2. HTTPS須要使用一套CA數字證書,證書內會附帶一個公鑰Pub,而與之對應的私鑰Private保留在服務端不公開;
  3. 服務端收到請求,返回配置好的包含公鑰Pub的證書給客戶端;
  4. 客戶端收到證書,校驗合法性,主要包括是否在有效期內、證書的域名與請求的域名是否匹配,上一級證書是否有效(遞歸判斷,直到判斷到系統內置或瀏覽器配置好的根證書),若是不經過,則顯示HTTPS警告信息,若是經過則繼續;
  5. 客戶端生成一個用於對稱加密的隨機Key,並用證書內的公鑰Pub進行加密,發送給服務端;
  6. 服務端收到隨機Key的密文,使用與公鑰Pub配對的私鑰Private進行解密,獲得客戶端真正想發送的隨機Key
  7. 服務端使用客戶端發送過來的隨機Key對要傳輸的HTTP數據進行對稱加密,將密文返回客戶端;
  8. 客戶端使用隨機Key對稱解密密文,獲得HTTP數據明文;
  9. 後續HTTPS請求使用以前交換好的隨機Key進行對稱加解密。

對稱加密與非對稱加密

又是對稱加密又是非對稱加密,一會公鑰一會私鑰一會隨機Key,爲何要這麼複雜呢,一套搞到底很差麼?

對稱加密是指有一個密鑰,用它能夠對一段明文加密,加密以後也只能用這個密鑰來解密獲得明文。若是通訊雙方都持有密鑰,且天知地知你知我知,絕對不會有別的人知道,那麼通訊安全天然是能夠獲得保證的(在密鑰足夠強的狀況下)。

然而,在HTTPS的傳輸場景下,服務端事先並不知道客戶端是誰,你也不可能在事先不經過互聯網和每個網站的管理員都悄悄商量好一個通訊密鑰出來,那麼必然存在一個密鑰在互聯網上傳輸的過程,若是在傳輸過程當中被別人監聽到了,那麼後續的全部加密都是無用功。

這時,咱們就須要另外一種神奇的加密類型,非對稱加密。

非對稱加密有兩個密鑰,一個是公鑰,另外一個是私鑰。通常來講,公鑰用來加密,這時密文只能用私鑰才能解開。

那麼,當客戶端發起鏈接請求,服務端將公鑰傳輸過去,客戶端利用公鑰加密好信息,再將密文發送給服務端,服務端裏有私鑰能夠解密。

可是,當服務端要返回數據,若是用公鑰加密,那麼客戶端並無私鑰用來解密,而若是用私鑰加密,客戶端雖然有公鑰能夠解密,但這個公鑰以前就在互聯網上傳輸過,頗有可能已經有人拿到,並不安全,因此這一過程只用非對稱加密是不能知足的。

注意,嚴格來說,私鑰並不能用來加密,只能用做簽名使用,這是因爲密碼學中生成公鑰私鑰時對不一樣變量的數學要求是不一樣的,所以公鑰私鑰抵抗攻擊的能力也不一樣,在實際使用中不可互換。簽名的功能在HTTPS裏也有用到,下文中會說明。

只有一組公鑰私鑰只能保證單程的加解密,那麼若是咱們準備兩組公鑰私鑰呢,是否是能夠解決這個問題?來看下面這個過程。

  1. 服務端有非對稱加密的公鑰A1,私鑰A2;
  2. 客戶端有非對稱加密的公鑰B1,私鑰B2;
  3. 客戶端向服務端發起請求,服務端將公鑰A1返回給客戶端;
  4. 瀏覽器收到公鑰A1,將本身保存的公鑰B1發送給服務端;
  5. 以後服務端全部向客戶端發送的數據,使用公鑰B1加密,客戶端可使用私鑰B2解密;
  6. 客戶端全部向服務端發送的數據,使用公鑰A1加密,服務端可使用私鑰A2解密。

此時,兩條傳輸方向的數據都通過非對稱加密,都能保證安全性,那麼爲何不採用這種方案呢?

最主要的緣由是非對稱加解密耗時要遠大於對稱加解密,對性能有很大損耗,你們的使用體驗不好。

因此,咱們才最終選用了上文介紹到非對稱加密+對稱加密的方案,再複習一下↓↓↓

  1. 服務端有非對稱加密的公鑰A1,私鑰A2;
  2. 客戶端發起請求,服務端將公鑰A1返回給客戶端;
  3. 客戶端隨機生成一個對稱加密的密鑰K,用公鑰A1加密後發送給服務端;
  4. 服務端收到密文後用本身的私鑰A2解密,獲得對稱密鑰K,此時完成了安全的對稱密鑰交換,解決了對稱加密時密鑰傳輸被人竊取的問題
  5. 以後雙方通訊都使用密鑰K進行對稱加解密。

看起來是一個很是完美的方案,兼顧了安全性和性能,可是,真的就安全了麼?

CA頒發機構

依然考慮中間人攻擊的狀況,非對稱加密的算法都是公開的,全部人均可以本身生成一對公鑰私鑰。

當服務端向客戶端返回公鑰A1的時候,中間人將其替換成本身的公鑰B1傳送給瀏覽器。

而瀏覽器此時一無所知,傻乎乎地使用公鑰B1加密了密鑰K發送出去,又被中間人截獲,中間人利用本身的私鑰B2解密,獲得密鑰K,再使用服務端的公鑰A1加密傳送給服務端,完成了通訊鏈路,而服務端和客戶端毫無感知。

HTTPS中間人
HTTPS中間人

出現這一問題的核心緣由是客戶端沒法確認收到的公鑰是否是真的是服務端發來的。爲了解決這個問題,互聯網引入了一個公信機構,這就是CA。

服務端在使用HTTPS前,去通過認證的CA機構申請頒發一份數字證書,數字證書裏包含有證書持有者、證書有效期、公鑰等信息,服務端將證書發送給客戶端,客戶端校驗證書身份和要訪問的網站身份確實一致後再進行後續的加密操做。

可是,若是中間人也聰明一點,只改動了證書中的公鑰部分,客戶端依然不能確認證書是否被篡改,這時咱們就須要一些防僞技術了。

前面說過,非對稱加密中通常公鑰用來加密,私鑰用來解密,雖然私鑰加密理論上可行,但因爲數學上的設計這麼作並不適合,那麼私鑰就只有解密這個功能了麼?

私鑰除了解密外的真正用途其實還有一個,就是數字簽名,其實就是一種防僞技術,只要有人篡改了證書,那麼數字簽名必然校驗失敗。具體過程以下

  1. CA機構擁有本身的一對公鑰和私鑰
  2. CA機構在頒發證書時對證書明文信息進行哈希
  3. 將哈希值用私鑰進行加簽,獲得數字簽名
明文數據和數字簽名組成證書,傳遞給客戶端。
  1. 客戶端獲得證書,分解成明文部分Text和數字簽名Sig1
  2. 用CA機構的公鑰進行解籤,獲得Sig2(因爲CA機構是一種公信身份,所以在系統或瀏覽器中會內置CA機構的證書和公鑰信息)
  3. 用證書裏聲明的哈希算法對明文Text部分進行哈希獲得T
  4. 當本身計算獲得的哈希值H與解籤後的Sig2相等,表示證書可信,沒有被篡改

這時,簽名是由CA機構的私鑰生成的,中間人篡改信息後沒法拿到CA機構的私鑰,保證了證書可信。

注意,這裏有一個比較難以理解的地方,非對稱加密的簽名過程是,私鑰將一段消息進行加簽,而後將簽名部分和消息自己一塊兒發送給對方,收到消息後對簽名部分利用公鑰驗籤,若是驗簽出來的內容和消息自己一致,代表消息沒有被篡改。

在這個過程當中,系統或瀏覽器中內置的CA機構的證書和公鑰成爲了相當重要的環節,這也是CA機構公信身份的證實,若是系統或瀏覽器中沒有這個CA機構,那麼客戶端能夠不接受服務端傳回的證書,顯示HTTPS警告。

實際上CA機構的證書是一條信任鏈,A信任B,B信任C,以掘金的證書爲例,掘金向RapidSSL申請一張證書,而RapidSSL的CA身份是由DigiCert Global根CA認證的,構成了一條信任鏈。

各級CA機構的私鑰是絕對的私密信息,一旦CA機構的私鑰泄露,其公信力就會一敗塗地。以前就有過幾回CA機構私鑰泄露,引起信任危機,各大系統和瀏覽器只能紛紛吊銷內置的對應CA的根證書。

有些老舊的網站會要求使用前下載安裝他本身的根證書,這就是這個網站使用的證書並不能在系統內置的CA機構和根證書之間造成一條信任鏈,須要本身安裝根證書來構成信任鏈,這裏的風險就要使用者本身承擔了。

證書明細
證書明細

總結

本文已收錄 Github https://github.com/ponkans/F2E,歡迎 Star,持續更新💧

HTTPS 的出發點是解決HTTP明文傳輸時信息被篡改和監聽的問題。

  • 爲了兼顧性能和安全性,使用了非對稱加密+對稱加密的方案。
  • 爲了保證公鑰傳輸中不被篡改,又使用了非對稱加密的數字簽名功能,藉助CA機構和系統根證書的機制保證了HTTPS證書的公信力。

近期原創文章傳送門,biubiubiu:


喜歡的小夥伴加個關注,點個贊哦,感恩💕😊

聯繫我 / 公衆號

微信搜索【接水怪】或掃描下面二維碼回覆」加羣「,我會拉你進技術交流羣。講真的,在這個羣,哪怕您不說話,光看聊天記錄也是一種成長。(阿里技術專家、敖丙做者、Java3y、蘑菇街資深前端、螞蟻金服安全專家、各路大牛都在)。

接水怪也會按期原創,按期跟小夥伴進行經驗交流或幫忙看簡歷。加關注,不迷路,有機會一塊兒跑個步🏃 ↓↓↓

相關文章
相關標籤/搜索