HTTPS 互聯網世界的安全基礎

近一年公司在努力推進全站的 HTTPS 化,作為負責應用系統的我們,在配合這個趨勢的過程中,順便也就想去搞清楚 HTTP 後面的這個 S 到底是個什麼含義?有什麼作用?帶來了哪些影響?畢竟以前也就只是模糊的知道大概是更安全,但到底怎麼變得更安全的,實際上整個細節和流程並沒有掌握的特別清晰。

所以這篇關於 HTTPS 的技術總結文章,主要提供一個關於 HTTPS 中的 S 一個整體的認識。從其產生的歷史背景、設計目標說起,到分析其協議設計結構、交互流程是如何實現其目標。最後結合我們自己的案例分析下其中帶來的影響。

下面我們就先從其誕生之初說起吧。

歷史

S 代表 Secure,所以 HTTPS 自然就是更安全的 HTTP 的意思。互聯網誕生之初 SSL(Secure Sockets Layer 安全套接層)是由 Netscape 這家最早的瀏覽器公司設計的,主要是用於 Web 的安全傳輸的協議,這種協議在早期 Web 上獲得了廣泛的應用。後來被 IETF 標準化形成了 TLS(Transport Layer Security 傳輸層安全)標準,其歷史如下:

  • 1994: SSL1.0,因為存在嚴重的安全漏洞,未發佈。
  • 1995: SSL2.0,這個版本由於設計缺陷,很快被發現有嚴重漏洞,被廢棄。
  • 1996: SSL3.0,重新設計並開始流行,SSL 前三個版本都是由 Netscape 設計實現。
  • 1999: TLS1.0,IETF 將 SSL 標準化,即 RFC 2246。
  • 2006: TLS1.1,作為 RFC 4346 發佈。
  • 2008: TLS1.2,作為 RFC 5246 發佈 。
  • 2015: TLS1.3,尚在制定中,處於草案階段。

如上,現在互聯網世界使用最廣泛的應該是 TLS1.2 標準。

目標

SSL/TLS 最初的設計目標就是為了實現下面三個目的:

  • 保密:第三方無法竊聽。
  • 完整:無法篡改。
  • 認證:防止身份冒充。

互聯網是一個開放的環境,十分複雜。網上兩端通信的雙方彼此都不知道誰是誰,雙方如何信任、信息如何保密,如何不被篡改,這是十分複雜的問題。而且互聯網本身就像有生命一般在不斷進化,如何設計一個協議來應對未來可能的變化,因而這使得 SSL/TLS 協議的設計十分複雜。

結構

我們知道整個互聯網構建於 TCP/IP 協議棧基礎之上,在描述協議設計細節之前,我們先看看 SSL/TLS 協議處於該分層協議棧結構中的位置,其分層結構位置參考如下:

HTTPS 互聯網世界的安全基礎

交互

SSL/TLS 協議設計之初就考慮了互聯網和安全算法生命週期的演變,所以設計了一個算法協商握手流程,允許未來隨著新安全算法的誕生可以靈活的加入到協議中,這就是典型的軟件可擴展性設計的範例。下面是協議握手流程:

HTTPS 互聯網世界的安全基礎

握手的目的簡單概括就是:通信雙方協商出一套會話密鑰,然後基於此密鑰通過對稱加密方式來安全通信。

Client Hello

握手交互流程,首先由 Client 端發起 ClientHello 請求。在這個請求中 Client 端向 Server 端提供如下信息:

  • SSL version : 自己支持的最高協議版本,比如 TLS1.2。
  • Ciphers : 支持的加密套件,比如: RSA 非對稱加密算法,AES 對稱加密算法。
  • Random number: Client 端隨機數,將會用來生成會話密鑰。

Server Hello

Server 收到 ClientHello 請求後需要回應一系列內容,從 ServerHello 到 ServerHelloDone,有些服務端的實現是每條單獨發送,有些服務端實現是合併到一起發送。

ServerHello

根據 Client 端的請求信息確認使用的協議版本和加密套件(Cipher Suite),和客戶端一致,並生成一個 Server 端隨機數,用來生成會話密鑰。

Certificate

Server 端用於證明自身身份的憑證,一種由專門的數字證書認證機構(Certificate Authority 簡稱 CA)通過非常嚴格的審核之後頒發的電子證書,由 Client 端去認證 Server 端的合法身份。

ServerKeyExchange

可選的,補充生成會話密鑰的信息。對於前面協商的有些加密算法若 Certificate 未提供足夠的信息或就沒有 Certificate 那麼需要發送該消息。進一步的細節我們就不深入了,可以查看參考[1]。

CertificateRequest

可選的,Server 端需要認證 Client 端身份的請求時發送。比如,銀行提供的各類 U 盾,其實就是一種 Client 證書,一般在線使用專業版網銀時才需要。

ServerHelloDone

表示 Server 響應結束。

Client Finished

Client 收到 Server 回應後,首先驗證 Server 的證書。如果證書不是可信機構頒佈、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。如果證書沒有問題,Client 會繼續回應 Server,包括如下內容:

Certificate

Client 端響應 Server 的 CertificateRequest 請求。

ClientKeyExchange

Client 再生成一個隨機數,又稱 premaster secret 用於生成會話密鑰的信息,並把這個隨機數傳遞給 Server 用於 Server 生成相同的會話密鑰。

CertificateVerify

用於對客戶端證書提供證明,對於特定的證書需要可選發送。

ChangeCipherSpec

用於告知 Server,Client 已經切換到之前協商好的加密套件(Cipher Suite)的狀態,準備使用之前協商好的加密套件和會話密鑰加密數據並傳輸了。

Finished

Client 會使用之前協商好的加密套件和會話密鑰加密一段 Finished 的數據傳送給 Server,此數據是為了在正式傳輸應用數據之前對剛剛握手建立起來的加解密通道進行驗證。

Server Finished

Server 在接收到客戶端傳過來的 premaster secret 數據之後,也會使用跟 Client 同樣的方式生成會話密鑰。一切就緒後,服務端回應如下內容:

NewSessionTicket

表示新建了一個會話票據,傳遞給 Client。若連接意外中斷 Client 需要重建會話時,可以複用該票據,加速握手過程。

ChangeCipherSpec

告知 Client 已經切換到協商過的加密套件狀態,準備使用加密套件和會話密鑰加密數據並傳輸了。

Finished

Server 會使用之前協商好的加密套件和會話密鑰加密一段 Finished 的數據傳送給 Client,此數據是為了在正式傳輸應用數據之前對剛剛握手建立起來的加解密通道進行驗證。

至此,整個握手階段全部結束。接下來 Client 和 Server 進入使用會話密鑰的加密通信過程。

認證

前面提及證書驗證部分屬於 SSL/TLS 協議中比較複雜的部分,我們單獨用一節分析下。證書是由 CA 簽發的,所以要驗證證書的有效性需要去 CA 的服務器,流程如下。

HTTPS 互聯網世界的安全基礎

在線證書狀態驗證採用了 OCSP(Online Certificate Status Protocol 在線證書狀態協議)協議去驗證。但如果按上面這個方式,那 HTTPS 就慢死了,不實用,所以有了 OCSP stapling 方式,其流程如下:

HTTPS 互聯網世界的安全基礎

Server 端會定期去 CA 同步一份經過 CA 認證簽名的證書狀態檢查結果並伴隨 ClientHello 響應返回給 Client 端。因為這個結果是 CA 自己通過數字簽名,Server 也無法偽造或篡改,因此 Client 可以信任這個結果,以達到減少不必要的步驟提升性能的效果。

另外,證書根據其認證類型可分為三類:

Domain Validation

DV 證書用於驗證一個或多個域名的所有權,無需遞交紙質文件,僅驗證域名管理權,無需人工驗證申請單位真實身份。

Organization Validation

OV 證書用於驗證此域名由特定組織或單位所擁有的域名。申請此類證書,通過證書頒發機構審查網站企業身份和域名所有權以證明申請單位是一個合法存在的真實實體,CA 機構將在人工核實後簽發證書。

Extended Validation

EV 證書是目前最高信任級別的證書。通過極其嚴格甚至苛刻審查網站企業身份和域名所有權,確保網站身份的真實可靠。

我們經常通過瀏覽器訪問一些安全級別比較高的網站時,都是基於 HTTPS 協議,這時瀏覽器會顯示一個綠色的「鎖型」標記,讓我們心理感到放心,比如下圖所示幾個例子:

招行

HTTPS 互聯網世界的安全基礎

支付寶

HTTPS 互聯網世界的安全基礎

GitHub

HTTPS 互聯網世界的安全基礎

上面三個圖,分別來自招商銀行、支付寶和 GitHub,看出它們的證書和加密套件的區別沒?其中招行和 GitHub 都是採用的 EV 證書,所以瀏覽器地址欄顯示了企業名稱,而支付寶採用的是 OV 證書因此沒有。另外招行的 TLS 協議是 1.0 版本,這是一個有已知安全漏洞的版本,瀏覽器提示了過時的連接安全設置。而支付寶採用的加密套件被提示屬於過時的(強度不是最高的,但沒有已知的安全漏洞),GitHub 採用的則應該是目前最推薦的安全加密算法套件:TLS1.2(協議版本) + ECDHE_RSA(密鑰協商交換) + AES_128_GCM(對稱加密)。

另外,SSL/TLS 協議中比較複雜的部分是關於加密套件的,這塊基本屬於密碼學背後的數學原理部分。一般碼農基本搞不懂(我也搞不懂),對於我們來說大概只需要搞清楚對稱加密、非對稱加密、HASH 算法的區別和時間開銷。在選擇密碼套件時知道哪類是哪類,跟上主流的選擇就行了。

案例

講完 SSL/TLS 的基本原理和交互流程,就以我所在的 IM 項目為例,這裡同時涉及 HTTP + S 和 TCP + S。HTTP 屬於全公司一起加 S,那就加在統一的負載均衡層,也就是 HAProxy 那裡,對整體應用無影響(參見下面部署結構圖)。而 IM 客戶端應用也可以間接通過 HTTPS 前置請求獲得對服務端的認證,然後選擇接入服務器建立 TCP 長連接。TCP 長連接實際只需要做加密保護,不再需要二次認證。

HTTPS 互聯網世界的安全基礎

一開始,我們是在自己的接入應用中,基於 JDK 的 SSL 庫實現的 TCP + S,但是發現在高併發壓力下發現性能衰退的厲害,後來便改成了使用 Nginx 前置接入的方式。對比性能測試如下所示:

HTTPS 互聯網世界的安全基礎

可以看出引入 SSL 後確實帶來了一些性能開銷,不過整體不大。


分享到:


相關文章: