我終於搞清了啥是 HTTPS 了
阿新 • • 發佈:2020-06-04
![](https://cdn.geekdigging.com/technique-sharing/20200530/http-vs-https.jpg)
## 引言
最近上海連續下了一週雨,溫度一夜之間回到解放前,穿夏裝的我被凍得瑟瑟發抖,躲在家裡哪也不想去。
![](https://cdn.geekdigging.com/technique-sharing/20200530/sesefadou.gif)
在家百無聊賴的刷著網頁,看到公眾號後臺的留言,有同學問我 HTTP 和 HTTPS 有啥區別?
這還用問,當然是 HTTPS 要比 HTTP 更加的安全啊,沒看到後面帶著個 S 呢麼,帶著 S 就這麼 NB 。
然後同學的下一個問題把我問懵逼了,為啥帶 S 的更安全呢?能詳細的講講麼。
我跟你講嗷,不是我吹,我這麼多年。。。。。。
就沒見過你這麼刨根究底的同學,老問這種我也不是很清楚的問題。
雖然這個問題問的我老臉一紅,但是我有一種不要臉的精神 「我不會,但是我可以學」 。
![](https://cdn.geekdigging.com/technique-sharing/20200530/liaobuqi.gif)
## HTTP
首先先來了解下 HTTP :
HTTP 協議全稱為:Hyper Text Transfer Protocol ,翻譯過來就是超文字傳輸協議,請不要質疑這個翻譯,我專門用百度翻譯翻了一下。
TCP/IP 四層模型應該都知道的,有資料鏈路層,網路層,傳輸層和應用層:
![](https://cdn.geekdigging.com/technique-sharing/20200530/tcpip.png)
而 HTTP 協議就是位於 TCP/IP 四層模型的應用層上。
![](https://cdn.geekdigging.com/technique-sharing/20200530/tcpip_1.png)
這裡很多人都會混淆 TCP 和 HTTP ,實際上 HTTP 是基於 TCP 連線基礎上的。
簡單的說, TCP 就是單純建立連線,不涉及任何我們需要請求的實際資料,簡單的傳輸。而 HTTP 是用來收發資料,即實際應用上來的。
HTTP 協議通過請求和響應在客戶端和服務端之間收發資料,進行通訊:
![](https://cdn.geekdigging.com/technique-sharing/20200530/request-response.png)
## HTTPS
HTTP 協議看起來好像沒啥問題,唯一的問題就是不夠安全,因為 HTTP 協議的傳輸方式完全是由明文傳輸的,不做任何加密,這就讓一些不懷好意的人有了可乘之機。
這種傳輸方式誘發了一種經典的攻擊方式:中間人攻擊。
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_1.png)
對於這種情況,最簡單的我們可以使用加密方案,比如使用 AES 加密,服務端和客戶端先約定一個隨機生成的金鑰 key ,後續的通訊中,所有的資訊都使用這個金鑰進行 AES 加密:
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_2.png)
這樣雖然後面的通訊過程安全了,但是我們在第一發送 AES 金鑰的時候還是存在被中間人攔截的風險,一旦中間人攔截到我們的金鑰,可用對金鑰進行更換或者直接解密請求內容:
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_3.png)
這時我們可以使用不對稱加密,來專門對金鑰的傳輸做一次額外的保護。
不對稱加密會有兩個金鑰,一個是公鑰,一個是私鑰。明文可以使用公鑰加密私鑰解密,也可以使用私鑰加密公鑰解密。
現在比較通用的非對稱加密演算法有 RSA 。
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_4.png)
看到這裡的同學一定在奇怪,既然都使用了不對稱加密,為啥只對 AES 的金鑰做不對稱加密,好像有多此一舉,完全可以對後續所有的通訊資訊全都使用不對稱加密。
因為不對稱加密相比較對稱加密效能上存在明顯的劣勢,可能你覺得在一個請求中多消耗幾 ms 或者幾 ns 無所謂,但是請求到達服務端是要進行解密,每個請求都多消耗幾 ms 累計起來還是非常可觀的。
上面這個方案看起來已經很安全了,中間人即使攔截到我們的公鑰,由於不知道我們的私鑰貌似也沒辦法解密。
實際上中間人完全不需要解密我們的資訊,他可以生成一對新的公私鑰傳送給客戶端進行攻擊,後續客戶端的通訊中間人使用自己創造的私鑰進行解密,然後通過服務端生成的公鑰進行加密返回給服務端:
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_5.png)
## CA 證書
上面的問題我們僅通過客戶端和服務端已經沒辦法了,這時候需要引入新的第三方機構,一個頒發 CA 證書的機構。
常見的第三方 CA 機構有:Symantec(賽門鐵克),Comodo(科莫多),GeoTrust(環度網信),GoDaddy,Thawte,daoRapidSSL 等等。
在中間人攻擊中,我們遇到的問題不是加密演算法不夠神奇,不是金鑰方式不夠嚴謹,而是我們沒有辦法向我們的客戶端表明我們給他的公鑰是我們的,是不是很像我沒辦法證明我是我的問題。
![](https://cdn.geekdigging.com/technique-sharing/20200530/qingzhengming.jpg)
所以第三方機構應運而生,第三方機構只做一件事情,將服務端的公鑰刻上了我們的名字(CA 證書),客戶端接收到公鑰之後,只需要來第三方機構這裡查詢,就能知道這個公鑰是不是真的伺服器,然後再將自己生成的 AES 金鑰使用 CA 證書中解密得到的公鑰進行加密後傳送給服務端。
![](https://cdn.geekdigging.com/technique-sharing/20200530/zhongjianrengongji_6.png)
最後服務端使用私鑰解密得到 AES 金鑰,就可以愉快的和客戶端進行通訊了。
最後的最後,CA 機構驗證不是每次都要去 CA 機構查詢。這樣做太傻了而且太耗時,尤其是很多 CA 機構的服務都在海外,這樣一來一去消耗的時間太多了。
CA 機構高明的地方就在於,我們去找它註冊公鑰,它會使用另一個來註冊的公司的私鑰對我們的公鑰加密,得到一個我們的公鑰的指紋(全球唯一),然後將這家公司的公鑰資訊(其實也是證書)和我們的公鑰以及我們公鑰的指紋打包成一個證書。
當我們使用 HTTPS 將證書下發給客戶端校驗時,客戶端(比如瀏覽器)從證書中看到了上級證書的資訊,恰巧這個證書就在瀏覽器(或者本機)中,已經被驗證過是合法的,瀏覽器只要使用這個證書中的公鑰將我們的公鑰指紋進行解密,然後比對我們的公鑰資訊就知道我們也是的合法的。因為假證書中的公鑰簽名不可能被合法的上級證書中公鑰解密 。
這段稍微有點繞,慢慢看多看幾次就理解了。
## 參考
https://www.jianshu.com/p/691b8ba3a70f
https://blog.csdn.net/u010144805/article/details/80803059
https://blog.csdn.net/caofengtao1314/article/details/87912078