前言
主要記錄 https 加速的優化手段。
李柱明部落格:https://www.cnblogs.com/lizhuming/p/15486943.html
HTTPS 的連線很慢
https 步驟簡要劃分
HTTPS 連線大致分為兩個部分:
- 非對稱加密握手(TLS 握手);
- 對稱加密報文傳輸。
平時說的 HTTPS 很慢是前面第一部分,非對稱加密握手階段很慢。
而握手成功後是很快的。
握手耗時
TLS 握手最長可以花費兩個訊息往返(2-RTT)。
除了在握手訊息的網路耗時之外,還有:
- 產生用於金鑰交換的臨時公私鑰對(ECDHE);
- 驗證證書時訪問 CA 獲取 CRL 或者 OCSP;(這兩個知識點可以看後面)
- 非對稱加密解密處理“Pre-Master”。
不做優化的情況下,HTTPS 建立連線可能會比 HTTP 慢上幾百毫秒甚至幾秒。
TLS 握手過程中主要耗時圖參考:
-
優化就按照下圖耗時段進行優化。
證書驗證
本點只是做理解記錄,如果對 CRL 和 OCSP 有所理解,可以跳過。
CRL
CRL(Certificate revocation list)即是證書吊銷列表。
由 CA 定期釋出,裡面是所有被撤銷信任的證書序號。
查其內容即可知道本證書是否失效。
缺點:
- CRL 是定期釋出,如果證書失效了,但是 CA 機構還沒有及時更新 CRL,會導致誤判的安全隱患。
- 隨著吊銷的證書越來越多,下載的 CRL 就會越來越大了,檢索也越來越耗時。簡直就是越來越浪費空間浪費時間。
所以現在用 OCSP 取代 CRL。
OCSP
OCSP(Online Certificate Status Protocol)線上證書狀態協議。
客戶端將請求發到一個 OCSP 應答器(伺服器),應答器建立與 CA 證書庫連結查詢該證書的狀態,然後回覆“ 有效 ”、“ 登出 ”或“ 未知 ”的響應。
優點:
- 線上驗證比 CRL 處理速度更快、更方便,也更具獨立性。
- 並避免了令人頭痛的邏輯問題和處理開銷。
問題&解決:
-
OCSP 也要多出一次網路請求的消耗,而且還依賴於 CA 伺服器,如果 CA 伺服器很忙,也是很耗時的。
- 解決:OCSP Stapling:OCSP 裝訂,是一個補丁。可以讓伺服器預先訪問 CA 獲取 OCSP 響應,然後在握手時隨著證書一起發給客戶端,免去了客戶端連線 CA 伺服器查詢的時間。
硬體優化
HTTPS 連線是計算密集型,而不是 I/O 密集型:
- 計算密集型解決方法:加速計算。升級 CPU,硬體加速卡等等。
- I/O 密集型解決方法:升級網路卡、頻寬、SSD 儲存等等資料通訊裝置。
HTTPS 連線是計算密集型,而不是 I/O 密集型,其硬體優化手段有:
- 升級 CPU:如果內建 AES 優化,可以加速握手,也可以加速傳輸。
- SSL 加速卡:加解密時呼叫它的 API,讓專門的硬體來做非對稱加解密,分擔 CPU 的計算壓力。
- SSL 加速伺服器:用專門的伺服器叢集解決 TLS 握手時的加密解密計算,效能要比單純的“加速卡”要強大。
軟體優化
軟體方面的優化還可以再分成兩部分:一個是 軟體升級 ,一個是 協議優化 。
軟體升級
軟體升級,如升級 linux 核心,升級 OpenSSL 等等。
這些軟體在更新版本的時候都會做效能優化、修復錯誤,只要運維能夠主動配合,這種軟體優化是最容易做的,也是最容易達成優化效果的。
但是升級核心相容性要解決,版本跨度大,升級也是很棘手的。
協議優化
-
目前儘量採用 TLS1.3。
- 它大幅度簡化了握手的過程,完全握手只要 1-RTT,而且更加安全。
-
握手時使用的金鑰交換協議儘量選用橢圓曲線的 ECDHE 演算法。(RSA 在 TLS 1.3 中已經被廢棄)
- 運算速度快。
- 安全性高。
- 支援“False Start”,能夠把 TLS1.2 握手的訊息往返由 2-RTT 減少到 1-RTT,達到與 TLS1.3 類似的效果。
-
橢圓曲線也要選擇高效能的曲線。
- 最好是 x25519,次優選擇是 P-256。
-
對稱加密演算法方面,可以選用“AES_128_GCM”,比“AES_256_GCM”略快一點點。
證書優化
握手過程中的證書驗證也是一個比較耗時的操作,伺服器需要把自己的證書鏈全發給客戶端,然後客戶端接收後再逐一驗證。
兩個可優化點:
-
證書傳輸。
-
證書驗證。
-
伺服器的證書可以選擇橢圓曲線(ECDSA)證書而不是 RSA 證書。
- 因為 224 位的 ECC 相當於 2048 位的 RSA。證書小,傳輸就少,計算也少。
-
採用 OCSP 驗證證書。開啟 OCSP Stapling。
會話複用
大殺器。
連線同一伺服器時,明明證書、公鑰都一樣,但是每次通訊都需要重新 TLS 握手,重新驗證證書來獲取公鑰,算出對稱祕鑰。
這樣太浪費時間了,我們可以使用快取功能,雙方把會話 ID 和對稱祕鑰記錄下來,下次連結時直接使用豈不是更加方便快捷嗎,其實這就是會話複用。
會話複用(TLS session resumption),複用分兩種:
-
Session ID:客戶端和伺服器首次連線後各自儲存一個會話的 ID 號,記憶體裡儲存主金鑰和其他相關的資訊。
- 當客戶端再次連線時發一個 ID 過來,伺服器就在記憶體裡找,找到就直接用主金鑰恢復會話狀態,跳過證書驗證和金鑰交換,只用一個訊息往返就可以建立安全通訊。
- 缺點:伺服器儲存每一個客戶端的會話資料,對於擁有百萬、千萬級別使用者的網站來說儲存量就成了大問題,加重了伺服器的負擔。
-
Session Ticket:會話票證。下述。
Session ID:
會話票證
由於 Session ID 方案加重了伺服器負擔,所以出現了另一種方案,Session Ticket(會話票證)。
Session Ticket:會話票證。
- 儲存的責任由伺服器轉移到客戶端,即是伺服器會對會話記錄進行加密(如對稱主祕鑰、加密演算法等等)得到的 Ticket ,然後用 New Session Ticket 訊息發給客戶端,讓客戶端儲存。
- 重連的時候,客戶端使用擴充套件 session_ticket 傳送 Ticket 而不是 Session ID,伺服器解密後驗證有效期,就可以恢復會話,開始加密通訊。
- 不過 Session Ticket 方案需要使用一個固定的金鑰檔案(ticket_key)來加密 Ticket,為了防止金鑰被破解,保證“前向安全”,金鑰檔案需要定期輪換。
預共享金鑰
Pre-shared Key,簡稱為“PSK”,預共享金鑰。
False Start、Session ID、Session Ticket 等方式只能實現 1-RTT,而 TLS1.3 的 PSK 更進一步實現了 0-RTT。
原理和 Session Ticket 差不多,但在傳送 Ticket 的同時會帶上應用資料(Early Data),免去了伺服器確認步驟。
注意:
-
PSK 也不是完美的,它為了追求效率而犧牲了一點安全性,容易受到 重放攻擊(Replay attack)的威脅。黑客可以截獲 PSK 的資料,像復讀機那樣反覆向伺服器傳送。
- 解決:在訊息里加入時間戳、nonce 驗證,或者 一次性票證 限制重放。