看完還不懂HTTPS我直播吃翔

本文首發于我的個人技術博客看完還不懂HTTPS我直播吃翔

存在即合理

http是非常常見的應用層協議,是超文本傳輸協議的簡稱,其傳輸的內容都是明文的。在這個混亂的世界,明文傳輸信息想想就可怕,網絡“小混混”的手段遠比我們這些凡人高明得多,他們有一萬種方式劫持,篡改我們的數據。對于一個網站或者服務,如果你給你的用戶兩個選擇:

  1. 通訊數據明文傳輸,速度快;
  2. 通訊數據加密傳輸,但是速度可能會稍微慢一點.

我想,只要腦袋沒有長歪的用戶都寧愿犧牲一點速度去換取數據傳輸的安全。

這樣,https的存在就具備了合理性,https中的s表示SSL或者TLS,就是在原http的基礎上加上一層用于數據加密、解密、身份認證的安全層。

一層層揭開HTTPS神秘面紗

本文試圖通過層層漸進方式來通俗的闡述https的原理,若有錯誤,歡迎大家指正。

雖然要層層漸進,但是我們不妨先奉上剛畫好的還熱乎著的https通信完整流程圖:


從上圖可以看到,右邊有一堆鑰匙,一看到鑰匙我們就能想到這個過程免不了加密。另外,那些鑰匙長得還不一樣,有些只有一把,有些是一對,嗯,是的,你看得真仔細。

好的,扯遠了,現在開始層層漸進。

第一層(安全傳輸數據)

假如我們要實現一個功能:一個用戶A給一個用戶B發消息,但是要保證這個消息的內容只能被A和B知道,其他的無論是墨淵上神還是太上老君都沒辦法破解或者篡改消息的內容。

如上圖,需求就是這么簡單,A給B發一條消息,因為比較私密,不想被其他人看到。

由于消息不想被其他人看到,所以我們自然而然就會想到為消息加密,并且只有A和B才有解密的密鑰。這里需要考慮幾點:

  1. 使用什么加密方式?
  2. 密鑰怎么告知對方?

對于第一個問題,加密算法分為兩類:對稱加密和非對稱加密,這里我們選擇對稱機密,原因有如下幾個:

  1. 對稱加密速度快,加密時CPU資源消耗少;
  2. 非對稱加密對待加密的數據的長度有比較嚴格的要求,不能太長,但是實際中消息可能會很長(比如你給你女朋友發情書),因此非對稱加密就滿足不了;

對于第二個問題,這是導致整個https通信過程很復雜的根本原因。
如果A或B直接把他們之間用于解密的密鑰通過互聯網傳輸給對方,那一旦密鑰被第三者劫持,第三者就能正確解密A,B之間的通信數據。

第二層(安全傳輸密鑰)

通過第一層的描述,第二層需要解決的問題是:安全地傳輸A,B之間用于解密數據的密鑰。

因為如果傳輸過程中這把密鑰被第三者拿到了,就能解密傳通信數據,所以,這把密鑰必須得加密,就算第三者劫持到這把加密過的密鑰,他也不能解密,得到真正的密鑰。

這里有一個問題,那要用什么方式加密這把密鑰呢?如果使用對稱加密,那這個對稱加密的密鑰又怎么安全地告訴對方呢?完了,陷入死循環了.... 所以,一定不能用對稱加密

那就是用非對稱加密咯,那如何應用非對稱加密來加密那把密鑰呢?

考慮如下方式:


  1. 客戶端: 我要發起HTTPS請求,麻煩給我一個非對稱加密的公鑰;
  2. 服務器: (生成一對非對稱加密的密鑰對,然后把公鑰發給客戶端),接著,這是公鑰;
  3. 客戶端:(收到公鑰,生成一個隨機數,作為上圖中那一把密鑰,用剛才收到的公鑰加密這個密鑰,然后發給服務器)這是我剛生成的加密過的密鑰;
  4. 服務器:(收到加密后的密鑰,用本地的第一步自己生成的非對稱加密的私鑰解密,得到真正的密鑰);
  5. 現在,客戶端和服務器都知道了這把密鑰,就能愉快地用這個密鑰對稱加密數據...

分析一下上面步驟的可行性:

  • 上述步驟中最終用于加密數據的密鑰是客戶端生成并且用公鑰加密之后傳給服務器的,因為私鑰只有服務器才有,所以也就只有服務器才能解開客戶端上報的密鑰;
  • 要保證傳輸的密鑰只能被服務器解密,就得保證用于加密密鑰的公鑰一定是服務器下發的,絕對不可能被第三方篡改過;

因為還可能存在一種"中間人攻擊"的情況,如下圖:


感謝XngPro的指正,上圖第7步,應該是『壞人用B私鑰解密得到K,然后使用A公鑰加密發給服務器』

這種情況下,客戶端和服務器之間通信的數據就完全被壞人破解了。

第三層(安全傳輸公鑰)

從上一層可以知道,要保證數據的安全,就必須得保證服務器給客戶端下發的公鑰是真正的公鑰,而不是中間人偽造的公鑰。那怎么保證呢?

那就得引入數字證書了,數字證書是服務器主動去權威機構申請的,證書中包含了上一個圖中的加密過的A公鑰和權威機構的信息,所以服務器只需要給客戶端下發數字證書即可?,F在流程圖如下:



那數字證書中的A公鑰是如何加密的呢?

答案是非對稱加密,只不過這里是使用只有權威機構自己才有的私鑰加密。

等一下,既然A公鑰被權威機構的私鑰加密了,那客戶端收到證書之后怎么解密證書中的A公鑰呢?需要有權威機構的公鑰才能解密??!那這個權威機構的公鑰又是怎么安全地傳輸給客戶端的呢?感覺進入了雞生蛋,蛋生雞的悖論了~~

別慌,答案是權威機構的公鑰不需要傳輸,因為權威機構會和主流的瀏覽器或操作系統合作,將他們的公鑰內置在瀏覽器或操作系統環境中。客戶端收到證書之后,只需要從證書中找到權威機構的信息,并從本地環境中找到權威機構的公鑰,就能正確解密A公鑰。

這樣就絕對安全了嗎?既然權威技能能給服務器簽發數字證書,那為什么就不可能給中間人簽發數字證書呢?畢竟賺錢的生意權威機構也不會拒絕的呀。

試想一下:

服務器給客戶端下發數字證書時證書被中間人劫持了,中間人將服務器的證書替換成自己的證書下發給客戶端,客戶端收到之后能夠通過權威機構的公鑰解密證書內容(因為中間人的證書也是權威機構私鑰加密的),從而獲取公鑰,但是,這里的公鑰并不是服務器原本的A公鑰,而是中間人自己證書中的B公鑰。從第二層可知,如果不能保證客戶端收到的公鑰是服務器下發的,那整個通信數據的安全就沒法保證。簡單總結就是證書被調包~

所以,還得保證客戶端收到的證書就是服務器下發的證書,沒有被中間人篡改過。

第四層(安全傳輸證書)

這一層,我們的任務是:保證客戶端收到的證書是服務器下發的證書,沒有被中間人篡改過。

所以,這里就有兩個需求:

  • 證明證書內容沒有被第三方篡改過;
  • 證明證書是服務器下發的;

其實這些問題,數字證書本身已經提供方案了,數字證書中除了包含加密之后的服務器公鑰,權威機構的信息之外,還包含了證書內容的簽名(先通過Hash函數計算得到證書數字摘要,然后用權威機構私鑰加密數字摘要得到數字簽名),簽名計算方法以及證書對應的域名。這樣一來,客戶端收到證書之后:

  • 使用權威機構的公鑰解密數字證書,得到證書內容(服務器的公鑰)以及證書的數字簽名,然后根據證書上描述的計算證書簽名的方法計算一下當前證書的簽名,與收到的簽名作對比,如果一樣,表示證書一定是服務器下發的,沒有被中間人篡改過。因為中間人雖然有權威機構的公鑰,能夠解析證書內容并篡改,但是篡改完成之后中間人需要將證書重新加密,但是中間人沒有權威機構的私鑰,無法加密,強行加密只會導致客戶端無法解密,如果中間人強行亂修改證書,就會導致證書內容和證書簽名不匹配。所以證書簽名就能判斷證書是否被篡改
  • 再考慮證書被掉包的情況:中間人同樣可以向權威機構申請一份證書,然后在服務器給客戶端下發證書的時候劫持原證書,將自己的假證書下發給客戶端,客戶端收到之后依然能夠使用權威機構的公鑰解密證書,并且證書簽名也沒問題。但是這個時候客戶端還需要檢查證書中的域名和當前訪問的域名是否一致。如果不一致,會發出警告!

從上面的分析可以看到,數字證書中的信息確實能讓客戶端辨別證書的真偽。

怎么樣?經過這么幾句通俗的話,是不是對HTTPS的通信機制有了比較清晰的認識了。當然了,有一些可能是我胡扯的,不一定對,大家多多指正!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容