HTTPS相關優化手段

HTTPS連接大致上可以劃分爲兩個部分,第一個是建立連接時的非對稱加密握手,第二個是握手後的對稱加密報文傳輸
HTTPS比HTTP增加了一個TLS握手的步驟,這個步驟最長可以花費兩個消息往返,也就是2-RTT。而且在握手消息的網絡延時消耗外,還會有其他的一些“隱形”消耗,比如:

  • 產生用於密鑰交換的臨時公私鑰對(ECDHE);
  • 驗證證書時訪問CA獲取CRL或者OCSP;
  • 非對稱加密解密處理“Pre-Master”。

如下圖標識出來部分影響性能的部分:

硬件優化

HTTPS連接是計算密集型,而不是I/O密集型。所以,如果你花大價錢去買網卡、帶寬、SSD存儲就是“南轅北轍”了,起不到優化的效果。

  1. 選擇更快的CPU,最好還內建AES優化,這樣即可以加速握手,也可以加速傳輸
  2. 可以選擇“SSL加速卡”,加解密時調用它的API,讓專門的硬件來做非對稱加解密,分擔CPU的計算壓力。
  3. SSL加速服務器:用專門的服務器集羣來徹底“卸載”TLS握手時的加密解密計算,性能自然要比單純的“加速卡”要強大的多。

軟件優化

一個是軟件升級,一個是協議優化。

  • 軟件升級: 比如把Linux內核由2.x升級到4.x,把Nginx由1.6升級到1.16,把OpenSSL由1.0.1升級到1.1.0/1.1.1。

協議優化

  1. 如果有可能,應當儘量採用TLS1.3,它大幅度簡化了握手的過程,完全握手只要1-RTT,而且更加安全。
  2. 橢圓曲線也要選擇高性能的曲線,最好是x25519,次優選擇是P-256。對稱加密算法方面,也可以選用“AES_128_GCM”,它能比“AES_256_GCM”略快一點點。
  3. 在Nginx裏可以用“ssl_ciphers”“ssl_ecdh_curve”等指令配置服務器使用的密碼套件和橢圓曲線,把優先使用的放在前面,例如:
ssl_ciphers   TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:EECDH+CHACHA20;
ssl_ecdh_curve              X25519:P-256;

證書優化

除了密鑰交換,握手過程中的證書驗證也是一個比較耗時的操作,服務器需要把自己的證書鏈全發給客戶端,然後客戶端接收後再逐一驗證。
這裏就有兩個優化點,一個是證書傳輸,一個是證書驗證
使用OCSP(在線證書狀態協議): 向CA發送查詢請求,讓CA返回證書的有效狀態。
但是OCSP需要多發出一次網絡請求的消耗,還要依賴於CA服務器,如果CA服務器很忙,那響應也是等不起的。
OCSP Stapling(OCSP裝訂): 可以讓服務器預先訪問CA獲取OCSP響應,然後在握手時隨着證書一起發送給客戶端,免去了客戶端連接CA服務器查詢的時間。

會話複用

在HTTPS建立連接的過程中。顯示三次TCP握手,然後是TLS一次握手,這後一次握手的重點是算出主密鑰“Master Secret”。而主密鑰每次連接都要重新計算,未免有點太浪費了,如果能夠把“辛辛苦苦”算出來的主密鑰緩存一下“重用”,不就可以免去握手和計算的成本了。
會話複用分爲兩種:第一種“Session ID”: 就是客戶端和服務器首次連接後各自保存一個會話的ID號,內存裏存儲主密鑰和其他相關的信息。當客戶端再次連接時發一個ID過來,服務器就在內存裏找,找到就直接用主密鑰恢復會話狀態,跳過證書驗證和密鑰交換,只用一個消息往返就可以建立安全通信。
如下圖所示,在會話複用中,服務器在“ServerHello”消息後直接發送了“Change Cipher Spec”和“Finished”消息,複用會話完成了握手。

會話票證

“Session ID”是最早出現的會話複用技術,也是應用最廣的,但它也有缺點,服務器必須保存每一個客戶端的會話數據,對於擁有百萬、千萬級別用戶的網站來說存儲量就成了大問題,加重了服務器的負擔。
於是出現,第二種“Session Ticket”方案。
它有點類似HTTP的Cookie,存儲的責任由服務器轉移到了客戶端,服務器加密會話信息,用“New Session Ticket”消息發給客戶端,讓客戶端保存。
不過“Session Ticket”方案需要使用一個固定的密鑰文件(ticket_key)來加密Ticket,爲了防止密鑰被破解,保證“前向安全”,密鑰文件需要定期輪換,比如設置爲一小時或者一天。

預共享密鑰

“False Start”“Session ID”“Session Ticket”等方式只能實現1-RTT,而TLS1.3更進一步實現了“0-RTT”,原理和“Session Ticket”差不多,但在發送Ticket的同時會帶上應用數據(Early Data),免去了1.2裏的服務器確認步驟,這種方式叫“Pre-shared Key”,簡稱爲“PSK”。

但“PSK”也不是完美的,它爲了追求效率而犧牲了一點安全性,容易受到“重放攻擊”(Replay attack)的威脅。黑客可以截獲“PSK”的數據,像復讀機那樣反覆向服務器發送。

解決的辦法是隻允許安全的GET/HEAD方法,在消息里加入時間戳、“nonce”驗證,或者“一次性票證”限制重放。

參考資料

以上內容參考極客時間《透視HTTP協議》課程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章