爲什麼HTTPS是安全的?90%的程序員沒搞清楚

來自:掘金,作者:MonkeyWie
鏈接:https://juejin.im/post/6870015164373008398

近幾年,互聯網發生着翻天覆地的變化,尤其是我們一直習以爲常的 HTTP 協議在逐漸的被 HTTPS 協議所取代,那麼,爲什麼要用 HTTPS?因爲 HTTP 不安全!

HTTP 協議

在談論 HTTPS 協議之前,先來回顧一下 HTTP 協議的概念。

HTTP 協議介紹

HTTP 協議是一種基於文本的傳輸協議,它位於 OSI 網絡模型中的應用層。

HTTP 協議是通過客戶端和服務器的請求應答來進行通訊,目前協議由之前的 RFC 2616 拆分成立六個單獨的協議說明(RFC 7230、RFC 7231、RFC 7232、RFC 7233、RFC 7234、RFC 7235),通訊報文如下:

請求:

POST http://www.baidu.com HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Content-Length: 7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

wd=HTTP

響應:

HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Thu, 14 Feb 2019 07:23:49 GMT
Transfer-Encoding: chunked

<html>...</html>

HTTP 中間人攻擊

HTTP 協議使用起來確實非常的方便,但是它存在一個致命的缺點:不安全。

我們知道 HTTP 協議中的報文都是以明文的方式進行傳輸,不做任何加密,這樣會導致什麼問題呢?

下面來舉個例子:

小明在 Java 貼吧發帖,內容爲我愛 java:

被中間人進行攻擊,內容修改爲我愛 PHP:

小明被羣嘲(手動狗頭)

可以看到在 HTTP 傳輸過程中,中間人能看到並且修改 HTTP 通訊中所有的請求和響應內容,所以使用 HTTP 是非常的不安全的。

防止中間人攻擊

這個時候可能就有人想到了,既然內容是明文那我使用對稱加密的方式將報文加密這樣中間人不就看不到明文了嗎,於是如下改造:

雙方約定加密方式,如下圖:

使用 AES 加密報文,如下圖:

這樣看似中間人獲取不到明文信息了,但其實在通訊過程中還是會以明文的方式暴露加密方式和祕鑰,如果第一次通信被攔截到了,那麼祕鑰就會泄露給中間人,中間人仍然可以解密後續的通信,如下圖:

那麼對於這種情況,我們肯定就會考慮能不能將祕鑰進行加密不讓中間人看到呢?答案是有的,採用非對稱加密,我們可以通過 RSA 算法來實現。

在約定加密方式的時候由服務器生成一對公私鑰,服務器將公鑰返回給客戶端,客戶端本地生成一串祕鑰(AES_KEY)用於對稱加密,並通過服務器發送的公鑰進行加密得到(AES_KEY_SECRET),之後返回給服務端。

服務端通過私鑰將客戶端發送的 AES_KEY_SECRET 進行解密得到 AEK_KEY,最後客戶端和服務器通過 AEK_KEY 進行報文的加密通訊。

改造如下圖:

可以看到這種情況下中間人是竊取不到用於 AES 加密的祕鑰,所以對於後續的通訊是肯定無法進行解密了,那麼這樣做就是絕對安全了嗎?

所謂道高一尺魔高一丈,中間人爲了對應這種加密方法又想出了一個新的破解方案,既然拿不到 AES_KEY,那我就把自己模擬成一個客戶端和服務器端的結合體。

在用戶→中間人的過程中中間人模擬服務器的行爲,這樣可以拿到用戶請求的明文,在中間人→服務器的過程中中間人模擬客戶端行爲,這樣可以拿到服務器響應的明文,以此來進行中間人攻擊:

這一次通信再次被中間人截獲,中間人自己也僞造了一對公私鑰,並將公鑰發送給用戶以此來竊取客戶端生成的 AES_KEY,在拿到 AES_KEY 之後就能輕鬆的進行解密了。

中間人這樣爲所欲爲,就沒有辦法制裁下嗎,當然有啊,接下來我們看看 HTTPS 是怎麼解決通訊安全問題的。

HTTPS 協議

HTTPS 簡介

HTTPS 其實是 SSL+HTTP 的簡稱,當然現在 SSL 基本已經被 TLS 取代了,不過接下來我們還是統一以 SSL 作爲簡稱。

SSL協議其實不止是應用在 HTTP 協議上,還在應用在各種應用層協議上,例如:FTP、WebSocket。

其實 SSL 協議大致就和上一節非對稱加密的性質一樣,握手的過程中主要也是爲了交換祕鑰,然後再通訊過程中使用對稱加密進行通訊。

大概流程如下:

這裏我只是畫了個示意圖,其實真正的 SSL 握手會比這個複雜的多,但是性質還是差不多,而且我們這裏需要關注的重點在於 HTTPS 是如何防止中間人攻擊的。

通過上圖可以觀察到,服務器是通過 SSL 證書來傳遞公鑰,客戶端會對 SSL 證書進行驗證,其中證書認證體系就是確保 SSL 安全的關鍵,接下來我們就來講解下 CA 認證體系,看看它是如何防止中間人攻擊的。

CA 認證體系

上一節我們看到客戶端需要對服務器返回的 SSL 證書進行校驗,那麼客戶端是如何校驗服務器 SSL 證書的安全性呢。

權威認證機構在 CA 認證體系中,所有的證書都是由權威機構來頒發,而權威機構的 CA 證書都是已經在操作系統中內置的,我們把這些證書稱之爲CA根證書:

簽發證書我們的應用服務器如果想要使用 SSL 的話,需要通過權威認證機構來簽發 CA 證書,我們將服務器生成的公鑰和站點相關信息發送給 CA 簽發機構,再由 CA 簽發機構通過服務器發送的相關信息用 CA 簽發機構進行加簽。

由此得到我們應用服務器的證書,證書會對應的生成證書內容的簽名,並將該簽名使用 CA 簽發機構的私鑰進行加密得到證書指紋,並且與上級證書生成關係鏈。

這裏我們把百度的證書下載下來看看:

可以看到百度是受信於 GlobalSign G2,同樣的 GlobalSign G2 是受信於 GlobalSign R1。

當客戶端(瀏覽器)做證書校驗時,會一級一級的向上做檢查,直到最後的根證書,如果沒有問題說明服務器證書是可以被信任的。

如何驗證服務器證書那麼客戶端(瀏覽器)又是如何對服務器證書做校驗的呢?

首先會通過層級關係找到上級證書,通過上級證書裏的公鑰來對服務器的證書指紋進行解密得到簽名(sign1),再通過簽名算法算出服務器證書的簽名(sign2)。

通過對比 sign1 和 sign2,如果相等就說明證書是沒有被篡改也不是僞造的。

這裏有趣的是,證書校驗用的 RSA 是通過私鑰加密證書籤名,公鑰解密來巧妙的驗證證書有效性。

這樣通過證書的認證體系,我們就可以避免了中間人竊取 AES_KEY 從而發起攔截和修改 HTTP 通訊的報文。

總結

首先先通過對 HTTP 中間人攻擊的來了解到 HTTP 爲什麼是不安全的,然後再從安全攻防的技術演變一直到 HTTPS 的原理概括,希望能讓大家對 HTTPS 有個更深刻的瞭解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章