也許,這樣理解HTTPS更容易

本文嘗試一步步還原HTTPS的設計過程,以理解爲何HTTPS最終會是這副模樣。可是這並不表明HTTPS的真實設計過程。在閱讀本文時,你能夠嘗試放下已有的對HTTPS的理解,這樣更利於「還原」過程。html

咱們先不了聊HTTP,HTTPS,咱們先從一個聊天軟件提及,咱們要實現A能發一個hello消息給B:git

若是咱們要實現這個聊天軟件,本文只考慮安全性問題,要實現算法

A發給B的hello消息包,即便被中間人攔截到了,也沒法得知消息的內容segmentfault

如何作到真正的安全?

這個問題,不少人立刻就想到了各類加密算法,什麼對稱加密、非對稱加密、DES、RSA、XX、噼裏啪啦~瀏覽器

而我想說,加密算法只是解決方案,咱們首先要作的是理解咱們的問題域——什麼是安全?安全

我我的的理解是:性能優化

A與B通訊的內容,有且只有A和B有能力看到通訊的真正內容服務器

好,問題域已經定義好了(現實中固然不止這一種定義)。對於解決方案,很容易就想到了對消息進行加密。網絡

題外話,可是隻有這一種方法嗎?我看未必,說不定在未來會出現一種物質打破當前世界的通訊假設,實現真正意義上的保密。性能

對於A與B這樣的簡單通訊模型,咱們很容易作出選擇:對稱加密算法

這就是對稱加密算法,其中圖中的密鑰S同時扮演加密和解密的角色。具體細節不是本文範疇。

只要這個密鑰S不公開給第三者,同時密鑰S足夠安全,咱們就解決了咱們一開始所定問題域了。由於世界上有且只有A與B知道如何加密和解密他們之間的消息。

可是,在WWW環境下,咱們的Web服務器的通訊模型沒有這麼簡單:

Web服務器使用對稱加密算法

若是服務器端對全部的客戶端通訊都使用一樣的對稱加密算法,無異於沒有加密。那怎麼辦呢?即能使用對稱加密算法,又不公開密鑰?請讀者思考21秒鐘。😜

答案是:Web服務器與每一個客戶端使用不一樣的對稱加密算法:

Web服務器與每一個客戶端使用不一樣對稱加密算法

如何肯定對稱加密算法

慢着,另外一個問題來了,咱們的服務器端怎麼告訴客戶端該使用哪一種對稱加密算法?

固然是經過協商。

協商對稱加密算法

可是,你協商的過程是沒有加密的,仍是會被中間人攔截。那咱們再對這個協商過程進行對稱加密就行了,那你對協商過程加密的加密仍是沒有加密,怎麼辦?再加密不就行了……好吧,進行雞生蛋蛋生雞的問題了。

如何對協商過程進行加密

新問題來了,如何對協商過程進行加密?密碼學領域中,有一種稱爲「非對稱加密」的加密算法,特色是私鑰加密後的密文,只要是公鑰,均可以解密,可是公鑰加密後的密文,只有私鑰能夠解密。私鑰只有一我的有,而公鑰能夠發給全部的人

非對稱加密

雖然服務器端向A、B……的方向仍是不安全的,可是至少A、B向服務器端方向是安全的。

好了,如何協商加密算法的問題,咱們解決了:使用非對稱加密算法進行對稱加密算法協商過程。

這下,你明白爲何HTTPS同時須要對稱加密算法和非對稱加密算法了吧?

協商什麼加密算法

要達到Web服務器針對每一個客戶端使用不一樣的對稱加密算法,同時,咱們也不能讓第三者知道這個對稱加密算法是什麼,怎麼辦?

使用隨機數,就是使用隨機數來生成對稱加密算法。這樣就能夠作到服務器和客戶端每次交互都是新的加密算法、只有在交互的那一該才肯定加密算法。

這下,你明白爲何HTTPS協議握手階段會有這麼多的隨機數了吧。

如何獲得公鑰?

細心的人可能已經注意到了若是使用非對稱加密算法,咱們的客戶端A,B須要一開始就持有公鑰,要不無法開展加密行爲啊。

這下,咱們又遇到新問題了,如何讓A、B客戶端安全地獲得公鑰?

我能想到的方案只有這些:

方案1. 服務器端將公鑰發送給每個客戶端

方案2. 服務器端將公鑰放到一個遠程服務器,客戶端能夠請求獲得

咱們選擇方案1,由於方案2又多了一次請求,還要另外處理公鑰的放置問題。

公鑰被調包了怎麼辦?又是一個雞生蛋蛋生雞問題?

可是方案1有個問題:若是服務器端發送公鑰給客戶端時,被中間人調包了,怎麼辦?

我畫了張圖方便理解:

中間人將公鑰攔截了

顯然,讓每一個客戶端的每一個瀏覽器默認保存全部網站的公鑰是不現實的。

使用第三方機構的公鑰解決雞生蛋蛋生雞問題

公鑰被調包的問題出現,是由於咱們的客戶端沒法分辨返回公鑰的人究竟是中間人,仍是真的服務器。這其實就是密碼學中提的身份驗證問題。

若是讓你來解決,你怎麼解決?若是你瞭解過HTTPS,會知道使用數字證書來解決。可是你想過證書的本質是什麼麼?請放下你對HTTPS已有的知識,本身嘗試找到解決方案。

我是這樣解決的。既然服務器須要將公鑰傳給客戶端,這個過程自己是不安全,那麼咱們爲何不對這個過程自己再加密一次?但是,你是使用對稱加密,仍是非對稱加密?這下好了,我感受又進了雞生蛋蛋生雞問題了。

問題的難點是若是咱們選擇直接將公鑰傳遞給客戶端的方案,咱們始終沒法解決公鑰傳遞被中間人調包的問題。

因此,咱們不能直接將服務器的公鑰傳遞給客戶端,而是第三方機構使用它的私鑰對咱們的公鑰進行加密後,再傳給客戶端。客戶端再使用第三方機構的公鑰進行解密。

下圖就是咱們設計的初版「數字證書」,證書中只有服務器交給第三方機構的公鑰,並且這個公鑰被第三方機構的私鑰加密了:

初版數字證書的內容

若是能解密,就說明這個公鑰沒有被中間人調包。由於若是中間人使用本身的私鑰加密後的東西傳給客戶端,客戶端是沒法使用第三方的公鑰進行解密的。

開始引入第三方機構

話到此,我覺得解決問題了。可是現實中HTTPS,還有一個數字簽名的概念,我無法理解它的設計理由。

原來,我漏掉了一個場景:第三方機構不可能只給你一家公司製做證書,它也可能會給中間人這樣有壞心思的公司發放證書。這樣的,中間人就有機會對你的證書進行調包,客戶端在這種狀況下是沒法分辨出是接收的是你的證書,仍是中間人的。由於不論中間人,仍是你的證書,都能使用第三方機構的公鑰進行解密。像下面這樣:

第三方機構向多家公司頒發證書的狀況:第三方機構向多家公司頒發證書的狀況

客戶端能解密同一家第三機構頒發的全部證書:客戶端能解密同一家第三機構頒發的全部證書

最終致使其它持有同一家第三方機構證書的中間人能夠進行調包:

證書依然能夠被中間人調包

數字簽名,解決同一機構頒發的不一樣證書被篡改問題

要解決這個問題,咱們首先要想清楚一個問題,辨別同一機構下不一樣證書的這個職責,咱們應該放在哪?

只能放到客戶端了。意思是,客戶端在拿到證書後,本身就有能力分辨證書是否被篡改了。如何纔能有這個能力呢?

咱們從現實中找靈感。好比你是HR,你手上拿到候選人的學歷證書,證書上寫了持證人,頒發機構,頒發時間等等,同時證書上,還寫有一個最重要的:證書編號!咱們怎麼鑑別這張證書是的真僞呢?只要拿着這個證書編號上相關機構去查,若是證書上的持證人與現實的這個候選人一致,同時證書編號也能對應上,那麼就說明這個證書是真實的。

咱們的客戶端能不能採用這個機制呢?像這樣:

但是,這個「第三方機構」究竟是在哪呢?是一個遠端服務?不可能吧?若是是個遠端服務,整個交互都會慢了。因此,這個第三方機構的驗證功能只能放在客戶端的本地了。

客戶端本地怎麼驗證證書呢?

客戶端本地怎麼驗證證書呢?答案是證書自己就已經告訴客戶端怎麼驗證證書的真僞。

也就是證書上寫着如何根據證書的內容生成證書編號。客戶端拿到證書後根據證書上的方法本身生成一個證書編號,若是生成的證書編號與證書上的證書編號相同,那麼說明這個證書是真實的。

同時,爲避免證書編號自己又被調包,因此使用第三方的私鑰進行加密。

這地方有些抽象,咱們來個圖幫助理解:

證書的製做如圖所示。證書中的「編號生成方法MD5」就是告訴客戶端:你使用MD5對證書的內容求值就能夠獲得一個證書編號。

當客戶端拿到證書後,開始對證書中的內容進行驗證,若是客戶端計算出來的證書編號與證書中的證書編號相同,則驗證經過:

可是第三方機構的公鑰怎麼跑到了客戶端的機器中呢?世界上這麼多機器。

其實呢,現實中,瀏覽器和操做系統都會維護一個權威的第三方機構列表(包括它們的公鑰)。由於客戶端接收到的證書中會寫有頒發機構,客戶端就根據這個頒發機構的值在本地找相應的公鑰。

題外話:若是瀏覽器和操做系統這道防線被破了,就沒辦法。想一想當年本身裝過的很是規XP系統,都懼怕。

說到這裏,想必你們已經知道上文所說的,證書就是HTTPS中數字證書,證書編號就是數字簽名,而第三方機構就是指數字證書籤發機構(CA)。

CA如何頒發數字證書給服務器端的?

當我聽到這個問題時,我誤覺得,咱們的SERVER須要髮網絡請求到CA部門的服務器來拿這個證書。😭 究竟是我理解能力問題,仍是。。

其實,問題應該是CA如何頒發給咱們的網站管理員,而咱們的管理員又如何將這個數字證書放到咱們的服務器上。

咱們如何向CA申請呢?每一個CA機構都大同小異,我在網上找了一個:申請數字證書

拿到證書後,咱們就能夠將證書配置到本身的服務器上了。那麼如何配置?這是具體細節了,留給你們google了。

也許咱們須要整理一下思路

咱們經過推算的方式嘗試還原HTTPS的設計過程。這樣,咱們也就明白了爲何HTTPS比HTTP多那麼屢次的交互,爲何HTTPS的性能會差,以及找到HTTPS的性能優化點。

而上面一大堆工做都是爲了讓客戶端與服務器端安全地協商出一個對稱加密算法。這就是HTTPS中的SSL/TLS協議主要乾的活。剩下的就是通訊時雙方使用這個對稱加密算法進行加密解密。

如下是一張HTTPS協議的真實交互圖(從網上copy的,忘了從哪了,若是侵權麻煩告知):

TLS協議

能不能用一句話總結HTTPS?

答案是不能,由於HTTPS自己實在太複雜。可是我仍是嘗試使用一段話來總結HTTPS:

HTTPS要使客戶端與服務器端的通訊過程獲得安全保證,必須使用的對稱加密算法,可是協商對稱加密算法的過程,須要使用非對稱加密算法來保證安全,然而直接使用非對稱加密的過程自己也不安全,會有中間人篡改公鑰的可能性,因此客戶端與服務器不直接使用公鑰,而是使用數字證書籤發機構頒發的證書來保證非對稱加密過程自己的安全。這樣經過這些機制協商出一個對稱加密算法,就此雙方使用該算法進行加密解密。從而解決了客戶端與服務器端之間的通訊安全問題。

好長的一段話。

後記

以上是我的爲理解HTTPS而編造出來的自圓其說的見解。頂多只能算是HTTPS的科普文章。若有錯誤,請指出,萬分感謝。

那麼,我爲何會以爲以這種方式理解HTTPS會更容易呢?我我的給出的答案是:當你本身爲一家人作一次菜時,你就會理解媽媽每天作菜的不易了。

學習資料:

相關文章
相關標籤/搜索