為什麼

在HTTP剛被發明出來的時候,網頁都是沒有加密的,這就意味著你在瀏覽器中填寫的所有信息,都有可能被其他人所竊取以及篡改。

想像一個場景,韓梅梅和李雷上課偷偷的傳紙條,小剛坐在兩人中間位置。由於韓梅梅和李雷互相不認識對方的簽名和字跡,小剛不僅可以偷偷的看紙條的內容,還可以自己對內容進行篡改,甚至假冒李雷給韓梅梅寫情書。

在這種情況下,我們肯定是沒辦法通過HTTP進行金融轉賬,聊天,甚至都沒法玩網路遊戲。

在1994年,網景公司(NetScape)推出了SSL 1.0版本,隨後又進行了版本升級。現在最新的版本是SSL3.0,TLS1.2等。而HTTPS,我們可以理解為經過SSL/TLS加持的HTTP(HTTP Over SSL/TLS)。

加密方式

那麼SSL/TLS是怎麼實現的呢?這裡我們要引入對稱加密和非對稱加密兩種加密方式。這兩類演算法是實現HTTPS的核心演算法。

我之前寫過文章介紹過最常見的非對稱加密演算法RSA,裡面詳細講解了非對稱加密的實現原理。今天我們不再詳細介紹演算法,只談各種演算法在HTTPS中有什麼用處。

非對稱加密演算法的特徵是有兩個秘鑰,一個是公鑰,一個是私鑰。公鑰加密的信息只有私鑰能解,私鑰加密的信息只有公鑰能解開。

我們想像一個場景,假設楊過和小龍女失去聯繫十多年,不幸小龍女在絕情谷呆久了變成了臉盲,這導致他們見面卻無法彼此相認。但是聰明的小龍女發現他們有一個玉佩,當年剛好摔成2半,一半(私鑰)在楊過身上,一半(公鑰)在小龍女那裡。只要楊過和小龍女的半塊玉佩能嚴絲合縫合在一起,他們就可以確認彼此的身份。

從這個特徵我們可以得知,非對稱加密主要用於身份認證,這在HTTPS起到一個非常重要的作用,普通用戶可以據此確認網站(例如銀行、電商)不是假冒的,不會把我們的錢騙走。

既然上面都解決了認證問題,那麼我們為什麼還需要對稱加密呢?這個主要的原因就是非對稱加密演算法性能不太好,當彼此確認身份之後,後面的通信就可以通過對稱加密來完成。

對稱加密演算法更好理解一點,它只有一個密鑰,既能加密信息也能解密信息。就好像一個鑰匙對應一把鎖,鑰匙是密鑰,鎖是加密的信息。在HTTPS通信會話中,伺服器和瀏覽器持有相同的鑰匙(秘鑰),他們之間的傳遞的消息就是鎖(加密信息)。

好了,我們可以總結一下HTTPS加密的過程。

  1. 瀏覽器和伺服器互相確認身份。
  2. 瀏覽器確認了伺服器身份後,交換秘鑰,開始通信。

好了,聰明一點的同學肯定就開始疑惑了,因為在上面假設的場景中,楊過還是可以騙小龍女的。假如楊過和人比武輸了,玉佩被人搶了,那小龍女豈不是被別人騙走了?但是小龍女聰明啊,她在對比玉佩之前,先找來歐陽鋒來認一下他乾兒子,在歐陽鋒確認無誤之後,她才可以確定眼前這個糙漢子是真的楊過。

上面這個場景里的歐陽鋒,其實就是HTTPS場景里的證書

證書

又有聰明的同學問問題了,小龍女不是臉盲嗎?她怎麼會認得歐陽鋒呢?

這個問題其實小龍女也會考慮,她雖然臉盲,但是她不蠢啊。她為了確定歐陽鋒的身份,她可以一直查下去,這樣她就可以孤獨終老了。

故事雖然荒謬,但是真實世界就是這樣的。在HTTPS的場景中,用戶的電腦其實已經預裝了很多根證書,這些是用戶可以無條件信任的。

證書上面會有其它證書對其進行簽名,最上面就是根證書,根證書自己證明自己是真的。

我們可以理解歐陽鋒是一個證書,那麼根證書就是金庸本人,金庸可以對所有武俠人物進行認證,但是他自己的身份就不用再證明了。

所以正版操作系統的信任鏈條的終點是微軟和蘋果這些信譽良好的巨頭公司以及他們信任的證書頒發機構,而盜版操作系統的信任鏈條,隨時可以被人植入非法的證書。

證書的作用我們已經知道了。那麼證書和網站之間的關係也很容易理解啦,證書頒發機構(CA)用自己的私鑰,對網站信息(網站地址,公鑰)進行簽名之後,發給網站。網站拿到簽名之後再給瀏覽器,瀏覽器將簽名和自己電腦上的根證書對比一看就能確認網站信息是否是偽造。

說的簡單一點,就是歐陽鋒和楊過之間,金庸和歐陽鋒之間,他們兩兩也有一對玉佩,他們3個能對上,那麼小龍女和楊過也能對上啦。

握手過程

好了,楊過和小龍女總算確認了彼此的身份,這個過程我們稱之為握手,雖然這個握手很麻煩,但是還是很形象的。

下面乾貨來了,我們詳細展開SSL的握手過程:

上圖是CloudFlare博客的SSL握手示意圖,左邊是瀏覽器,右邊是網站伺服器,雖然是英文,但是過程很好理解:

  1. 瀏覽器發送一個隨機數clientRandom到瀏覽器,同時還有支持的非對稱加密演算法(這裡是RSA)
  2. 伺服器拿到了clientRandom,生成了serverRandom和自己的公鑰證書等信息發給了瀏覽器
  3. 瀏覽器拿到了serverRandom之後,通過公鑰證書等信息確認伺服器的身份,生成一個新的隨機數parameterSecret,並通過伺服器公鑰加密,再發給伺服器
  4. 伺服器用自己的私鑰解密得到parameterSecret
  5. 現在伺服器和瀏覽器同時有用三個一樣的隨機數,clientRandom, serverRandom, paramterSecret,通過這3個數生成一個對稱加密的秘鑰,開始了愉快的加密會話過程

為什麼在之前的故事上,再加上3個隨機數呢,那是因為握手的過程是不加密的,這麼做是為了防止第三方突然跑進來篡改數據。一旦有一個隨機數不對,最後加密會話就無法建立,因為秘鑰不對。

會話秘鑰

因為瀏覽器和伺服器有相同的秘鑰,它們建立相互信任的通信會話就很好理解了。

如果會話中斷,那麼會話怎麼恢復呢?在上圖中,伺服器還向瀏覽器發送了一個會話ID(Session ID)。不同的會話(Session)的ID是不一樣的,當瀏覽器發送的請求帶有這個ID,伺服器確認之後,就可以恢復會話。

一般伺服器的會話ID是有時間限制的,中斷時間過長,再次通信就需要重新握手。

HTTPS中間人

理解了第一部分的根證書原理之後,我們就很容易理解Charles等軟體如何監聽HTTPS數據了。Chales會新建一個根證書以及一對公鑰私鑰,充當一個中間人身份,當用戶信任了這個根證書之後,Charles就可以監聽所有的加密會話了,詳細過程見下圖:

圖片來自 @rushjs https://www.jianshu.com/p/405f9d76f8c4

所以,既不要輕易安裝盜版操作系統,也不要輕易信任第三方給你的根證書。

總結

總的來說,HTTPS的過程可以分為兩部分:

  1. 握手建立信任,主要利用非對稱加密演算法(如RSA)以及第三方機構頒發的信任證書
  2. 建立信任後開始的加密會話

握手過程比較複雜,我們通過小龍女和楊過的相認過程來進行解釋。他們相認的過程不是無緣無故建立起來的,小龍女必須通過一個權威的第三方才能確認楊過的身份。

這也說明,在真實的陌生人世界中,建立信任是一個多麼難的事情,這個世界永遠也沒有100%的信任方案,但是我們還是可以建立正確的安全意識,只要操作得當,安全還是有保障的。


推薦閱讀:
查看原文 >>
相关文章