看完你就知道什麼是 HTTPS 了

Ceelog發表於2017-05-30

什麼是 HTTPS ?

不管是使用手機還是電腦上網,都離不開資料的通訊

現在網際網路上傳輸資料,普遍使用的是超文字傳輸協議,即 HTTP (HyperText Transfer Protocol)

所以,我們以前在上網的時候,會發現所有的網址都有一個 http:// 字首:

HTTP 協議

簡單而言,HTTP 協議定義了一套規範,讓客戶端或瀏覽器可以和伺服器正常通訊,完成資料傳輸

但是,HTTP 使用明文傳輸,比如你輸入賬號/密碼提交登入:

明文傳輸

很有可能被中間人竊聽,從而造成資料洩露,所以說 HTTP 是不安全的,現代瀏覽器會在位址列提示連線不安全:

火狐瀏覽器安全提示

為了解決安全傳輸的問題,人們發明了 HTTPS,即 HTTP + Secure

為什麼 HTTPS 是安全的?

只要把傳輸的資料加密,那麼通訊就是安全的,前提是除通訊雙方外,任何第三方無法解密:

加密傳輸

在上圖示例中,通訊的資料經過加密,即使被中間人竊聽到了,它也無法知道資料內容

火狐瀏覽器安全提示

HTTPS 是怎麼實現安全通訊的?

加密傳輸確實安全,但是客戶端把資料加密後,伺服器怎麼解密呢?又怎樣保證中間人竊聽到密文後無法解密呢?

答案是:使用對稱加密技術

什麼是對稱加密? 簡單而言,通訊雙方各有一把相同的鑰匙(所謂對稱),客戶端把資料加密鎖起來後,傳送給伺服器,伺服器再用鑰匙解密。同理,伺服器加密後傳輸給客戶端的資料,客戶端也可以用鑰匙解密

那麼,新的問題又出現了:怎樣在通訊之前,給雙方分配兩把一樣的鑰匙呢?

如果真的只有兩個人要通訊的話,可以簡單的私下見個面分配好,以後要通訊的時候用就行。但是,實際通訊往往是一個伺服器和成千上萬的客戶端之間,總不能讓每個人都和伺服器先私下見個面

另外,即使使用了對稱加密技術,如果一方保管不善的話,也有可能鑰匙被人偷了去複製一個,這樣就存在很大的安全隱患,最好是每個客戶端每次和伺服器通訊都用不同的金鑰

一個簡單的解決方案是:客戶端在每次請求通訊之前,先和伺服器協商,通過某種辦法,產生只有雙方知道的對稱金鑰

這個過程就是所謂:金鑰交換(Key Exchange)

金鑰交換演算法有很多種實現,常見的有:

  • Deffie-Hellman 金鑰交換演算法
  • RSA 金鑰交換演算法

本文以較簡單的 RSA 金鑰交換為例

簡單而言,RSA 金鑰交換演算法需要客戶端向伺服器提供一個 Pre-Master-Key,然後通訊雙方再生成 Master-Key,最後根據 Master-Key 產生後續一系列所需要的金鑰,包括傳輸資料的時候使用的對稱金鑰

那麼,客戶端怎麼把 Pre-Master-Key 告訴伺服器呢?直接明文傳輸麼?

我們之前說過,沒加密的通訊都會被竊聽,是不安全的

似乎進入死迴圈了:為了加密通訊,需要先把 Pre-Master-Key 傳送給伺服器,但是這個傳送又必須要加密

我們引入一種新的加密技術:非對稱加密

什麼是非對稱加密? 簡單而言,伺服器可以生成一對不同的金鑰(所謂非對稱),一把私自儲存,稱為私鑰;一把向所有人公開,稱為公鑰 這對金鑰有這樣的性質:公鑰加密後的資料只有私鑰能解密,私鑰加密後的資料只有公鑰能解密 非對稱加密的一種經典實現叫 RSA 演算法,這種加密演算法最早 1977 年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的,RSA 就是他們三人姓氏開頭字母拼在一起組成的

有了非對稱加密的技術後,事情就好辦了:

客戶端把 Pre-Master-Key 用伺服器的公鑰加密後,傳送給伺服器

因為只有伺服器才有私鑰,所以只有伺服器才能解密資料,獲取客戶端傳送來的 Pre-Master-Key

具體的互動過程:

  1. 客戶端向伺服器索取公鑰 PublicKey;
  2. 伺服器將公鑰發給客戶端(這裡沒有保密需求,因為公鑰是向所有人公開的);
  3. 客戶端使用伺服器的公鑰 PublicKey 把 Pre-Master-Key 加密成密文,傳送給伺服器;
  4. 伺服器用私鑰 PrivateKey 解密密文,獲取到客戶端傳送的 Pre-Master-Key;

看起來很完美,但是第 2 步驟又引發了一個新問題:

由於網際網路是公開的,伺服器傳送給客戶端的公鑰可能在傳送過程中被中間人截獲並篡改(所謂中間人攻擊 Man-in-the-middle attack,縮寫:MITM)

中間人攻擊

因為中間人也可以生成一對非對稱金鑰,它會截獲伺服器傳送的公鑰,然後把它自己的公鑰 MiddleMan-PublicKey 傳送給客戶端,進行欺騙

可憐我們的客戶端,竟然信以為真!然後傻乎乎的把自己的 Pre-Master-Key 用 MiddleMan-PublicKey 加密後,發給中間人

怎麼解決這個問題?

問題等價於:客戶端怎麼確定收到的公鑰,真的就是伺服器的公鑰?

想一想你乘高鐵、坐飛機的時候,怎麼向工作人員證明你是你

答案很簡單,到公安局(權威機構 英文名:Authority)出個身份證明(Certificate)

身份證上記載了你的號碼、姓名、年齡、照片、住址,還有簽發機關、有效期等

所以,伺服器也想辦法到權威機構 (Authority) 辦一張證書 Certificate,上面記載了伺服器的域名、公鑰、所屬單位,還有簽發機關、有效期等

當客戶端收到伺服器發過來的證書後,只要證書不是偽造的,那麼上面記載的公鑰肯定也就是真的!

證書長啥樣? 點選 IE 瀏覽器上的小鎖就可以檢視伺服器的證書

檢視證書

不過,這裡又有個新問題:怎麼證明證書不是偽造的?

我們介紹一種防偽手段:簽名(Signature)

什麼是簽名? 我們在生活、工作過程中,經常遇到需要簽名的情況:刷信用卡、籤合同等,用來證明這是本人的行為。簽名之所以可信,是因為理論上每個人的簽名都有生理學基礎,別人是無法偽造的,就像你的指紋一樣

所以,只要伺服器傳送的證書上有權威機構 Authority 的簽名,就可以確信證書是頒發給伺服器的,而不是誰偽造的

這就相當於,只要你的請假條上有領導的簽名,那麼 HR 就會確信領導已經審批同意你請假了

如果說人類簽名使用紙筆,那麼計算機的數字化簽名怎麼實現呢?

答案是使用非對稱加密技術:

  1. 數字證書認證機構(Certificate Authority,簡稱 CA)生成一對公/私鑰;
  2. 伺服器將自己的域名、公鑰等資訊提交給 CA 審查;
  3. CA 審查無誤,使用私鑰把伺服器資訊的摘要加密,生成的密文就是所謂簽名(Signature);
  4. CA 把伺服器的資訊、簽名、有效期等資訊集合到一張證書上,頒發給伺服器;
  5. 客戶端收到伺服器傳送的證書後,使用 CA 的公鑰解密簽名,獲得伺服器資訊的摘要,如果和證書上記錄的伺服器資訊的摘要一致,說明伺服器資訊是經過 CA 認可的

什麼是資訊摘要? 簡單來說,就是一段任意長的資料,經過資訊摘要處理後,可以得到一段固定長度的資料,比如 32 位元組,只要原始資料有任意變動,生成的資訊摘要都不一樣

但是,在第5步驟又有一個新問題:客戶端怎麼知道 CA 的公鑰?

答案:與生俱來

世界上的根 CA 就那麼幾家,瀏覽器或者作業系統在出廠的時候,已經內建了這些機構的自簽名證書,上面記錄他們的公鑰資訊,你也可以在需要的時候手動安裝 CA 證書

Windows 系統為例:

系統信任的根證書

至此,HTTPS 通訊過程已經很明朗了:

  1. 作業系統/瀏覽器 自帶了 CA 根證書;
  2. 客戶端因此可以驗證伺服器傳送的證書真實性,從而獲取到伺服器的公鑰;
  3. 有了伺服器的公鑰,客戶端就可以把 Pre-Master-Key 傳送給伺服器;
  4. 伺服器獲取到 Pre-Master-Key 後,通過後續產生的對稱金鑰,就可以和客戶端加密通訊了。

總結

本文簡述了 HTTPS 通訊過程的基本原理,涉及到了對稱加密、非對稱加密、資訊摘要、簽名、金鑰交換等技術基礎,以及發行機構、數字證書等概念

具體的 HTTPS 實現細節還要複雜得多,這裡並沒有展開講,但是並不影響對 HTTPS 不熟悉的讀者對原理有基本的認知

參考文獻

還有問題? 聯絡作者微博/微信 @Ceelog

關注作者微信公眾號

相關文章