服務端指南 | HTTPS 專案實戰指南

樑桂釗發表於2017-06-27

本文將重點介紹關於 HTTPS 的幾個實戰指南。

原文地址:服務端指南 | HTTPS 專案實戰指南
部落格地址:blog.720ui.com/

本文將重點介紹關於 HTTPS 的幾個實戰指南。

  1. HTTPS 使用剖析
  2. HTTPS 專案場景
  3. HTTPS 設計上的借鑑
  4. HTTPS 降級攻擊

HTTPS 使用剖析與專案場景

HTTP 協議沒有加密機制,可以通過 SSL 或 TLS 加密 HTTP 的通訊內容。因此,HTTPS 是 HTTP 的安全版,在 HTTP 協議中加入 SSL 層,它由兩部分組成:HTTP 與 SSL。其中,SSL 是獨立於 HTTP 的協議,它不僅可以適用於 HTTP 協議,還可以配合 WebSocket 等協議一起使用。

為什麼使用 HTTPS

HTTP 協議沒有加密機制,通訊內容是明文傳輸的,沒有經過任何安全處理。然而,網際網路的任何角落都可能存在通訊內容在傳輸過程中被中間者竊聽、篡改、冒充等風險。其中,任何角落指的是使用者的通訊內容在瀏覽器和伺服器中間傳輸必須要經過的節點,比如 WIFI 熱點,路由器,防火牆,反向代理,快取伺服器等。因此,HTTP 協議通訊存在的威脅不言而喻,中間者可以竊聽隱私,使使用者的敏感資訊洩露;篡改網頁,例如中間者向頁面插入廣告內容,甚至有的中間者進行流量劫持,例如有的時候會發現域名沒有輸錯,結果卻跳轉到了一個釣魚網站,因為這個網站被中間者劫持了。

因此,為了解決竊聽、篡改、冒充等風險,HTTPS 的價值就體現出來了,HTTPS 可以進行通訊內容加密,使第三方無法竊聽。HTTPS 可以進行身份認證,一旦通訊內容被篡改,通訊雙方會立刻發現。此外,HTTPS 可以保證通訊內容的完整性,防止通訊內容冒充或者篡改。

SSL 與 TLS

HTTP 協議可以通過 SSL 或 TLS 加密 HTTP 的通訊內容。其中,SSL 最初由網景通訊公司率先倡導與開發,最新版本是 SSL 3.0。目前,由 IETF 主導與管理。IETF 以 SSL 3.0 為基準,在 SSL 3.0 協議規範之上又制定了 TLS 1.0、 TLS 1.1 和 TLS 1.2。

HTTPS 原理剖析

為了更好地理解 HTTPS,先來觀察一下 HTTPS 的通訊步驟。

第一步,使用者在瀏覽器裡輸入一個支援 HTTPS 協議的網址,例如 blog.720ui.com,此時會發起一個 HTTPS 請求,通過 TCP 和伺服器建立連線,其中使用 443 埠。

第二步,伺服器向客戶端傳送證書,其中包括域名,申請證書的公司,證書的公鑰等資訊。

第三步,客戶端通過 SSL 或 TLS 對證書進行解析,驗證公鑰是否有效,例如驗證頒發機構與驗證過期時間等資訊,如果發現證書異常,則會彈出一個警告框,提示證書存在問題。如果證書沒有問題,那麼就生成一個金鑰,然後向伺服器傳送證書公鑰加密後的金鑰。

第四步,伺服器用證書私鑰進行解密,獲得客戶端傳過來的金鑰。

第五步,伺服器用客戶端的金鑰加密後的資訊傳送給客戶端。

第六步,客戶端用金鑰解密服務端傳過來的資訊,驗證服務端傳過來的資訊是否可以用金鑰進行解密。

第七步,客戶端用金鑰加密請求內容,然後將通訊內容傳送給服務端。

第六步,服務端用金鑰解密請求內容,並進行業務處理後用金鑰加密響應內容,然後將通訊內容傳送給客戶端。

在以上流程中,HTTPS 協議將對稱加密演算法與非對稱加密演算法的優勢相結合。使用對稱加密演算法對通訊內容進行快速加密,從而彌補了非對稱加密演算法處理速度慢的問題,並保證通訊內容的機密性。同時,使用非對稱加密演算法將對稱加密演算法的金鑰進行加密,保證對稱加密演算法的金鑰的安全交換。因此,HTTPS 協議先通過非對稱加密演算法進行金鑰的安全交換,並在建立通訊連線後,使用對稱加密演算法進行通訊,保證通訊內容的機密性。

HTTPS 專案場景

真實的業務場景是比較複雜的。這裡,整理 3 個專案中遇到的比較複雜的應用場景。

對 HTTPS 協議的通訊內容進行 CDN 加速

對 HTTPS 協議的通訊內容進行 CDN 加速主要兩個方案。

方案一,伺服器(源站)提供證書給 CDN 廠商,包括證書公鑰和證書私鑰,CDN 負責內容快取,CDN 有快取則直接響應,以 HTTP 或 HTTPS 的形式回源。這個方案,適用僅對防劫持、防篡改有需求,而願意提供證書給 CDN 的源站加速。

方案二,伺服器(源站)不提供證書給 CDN 廠商,因此 CDN 需要存放證書公鑰,伺服器(源站)存放證書私鑰。在 CDN 與瀏覽器進行 TLS 的認證和金鑰協商過程中,通過安全的通道把協商過程中的資訊以 HTTP 或 HTTPS 的形式轉發給源網站。這個方案,CDN 不做快取,僅以自有的加速網路,將使用者的請求快速送到伺服器(源站),降低公網延遲。因此,這個方案適用於對安全要求更高,不願將證書私鑰共享給 CDN 的源站加速。

對 HTTPS 的域名通過 CNAME 繫結到另外一個 HTTPS 域名上

對 HTTPS 的域名通過 CNAME 繫結到另外一個 HTTPS 域名上,這個情況下,需要兩個證書,因為每個證書跟自己的域名進行繫結,即使它們都在同一個伺服器上,也不能使用同一個證書。

兩臺伺服器的證書問題

因為安全問題,CA 證書部署在一臺伺服器上面,但是業務系統部署在另外一臺伺服器上面,這種情況就比較難辦。此時,需要藉助 Nginx 進行反向代理,回源到具體的伺服器。

HTTPS 設計上的借鑑

對稱加密演算法可以將敏感的資訊在通訊過程中通過 DES 或 AES 進行加密傳輸,然後在客戶端和服務端直接進行解密。但是,將金鑰編碼在程式碼中存在安全隱患,因為金鑰可能會洩漏。因此,更安全的做法是將金鑰儲存在資料庫中,由服務端的介面下發金鑰,在使用時由客戶端獲取金鑰並載入進記憶體,並且通過非對稱加密演算法保證金鑰在通訊過程中的安全交換。實際上,這個通訊流程可以借鑑 HTTPS 協議的流程,將對稱加密演算法與非對稱加密演算法的優勢相結合。其中,使用對稱加密演算法對通訊內容進行快速加密,從而彌補了非對稱加密演算法處理速度慢的問題,並保證通訊內容的機密性。同時,使用非對稱加密演算法將對稱加密演算法的金鑰進行加密,保證對稱加密演算法的金鑰的安全交換。

這裡,介紹一個檔案加密與解密的真實案例。需求場景是為了防止平臺資源被第三方抓取,因此需要對平臺的資源進行加密,並且只能用於平臺的客戶端使用。為了更好地理解整個通訊流程,先來觀察一下加密的通訊步驟。

第一步,客戶端 SDK 使用 RSA 加密演算法,生成一對公私鑰,或者稱之為加密金鑰與解密金鑰。

第二步,客戶端 SDK 向服務端請求 AES 金鑰,因為金鑰儲存在伺服器的資料庫中,由服務端的介面下發金鑰。其中,請求引數包括資源 ID 與 RSA 加密演算法的公鑰。

第三步,服務端使用客戶端 SDK請求引數中的資源 ID,生成一個 AES 金鑰,並儲存到資料庫中。

第四步,服務端使用客戶端 SDK請求引數中的 RSA 加密演算法的公鑰,加密AES 金鑰。

第五步,伺服器傳送給客戶端 SDK加密後的 AES 金鑰。

第六步,客戶端 SDK 使用RSA 加密演算法的私鑰解密,獲取到真正的 AES 金鑰。

第七步,客戶端 SDK 使用真正的 AES 金鑰對資原始檔進行加密。

理解了資原始檔的加密的通訊流程,再來觀察一下解密的通訊步驟。

與資原始檔的加密的通訊流程類似,客戶端 SDK 使用 RSA 加密演算法,生成一對公私鑰,客戶端 SDK 向服務端請求 AES 金鑰,服務端使用客戶端 SDK請求引數中的資源 ID 查詢 AES 金鑰,服務端使用客戶端 SDK請求引數中的 RSA 加密演算法的公鑰,加密AES 金鑰,並且伺服器傳送給客戶端 SDK加密後的 AES 金鑰,客戶端 SDK 使用RSA 加密演算法的私鑰解密,獲取到真正的 AES 金鑰,最後,客戶端 SDK 使用真正的 AES 金鑰對資原始檔進行解密。

HTTPS 降級攻擊的場景剖析與解決之道

HTTPS 一定安全麼

HTTP 協議沒有加密機制,通訊內容是明文傳輸的,沒有經過任何安全處理。因此,為了解決竊聽、篡改、冒充等風險,採用 HTTPS 協議。HTTPS 可以進行通訊內容加密,使第三方無法竊聽。HTTPS 可以進行身份認證,一旦通訊內容被篡改,通訊雙方會立刻發現。此外,HTTPS 可以保證通訊內容的完整性,防止通訊內容冒充或者篡改。那麼,使用了 HTTPS 就能確保通訊內容的安全傳輸嗎?理論上,是這樣的,但是事實上,現實卻不是如此,因為設計與實現 SSL/TLS 協議出現了漏洞,導致攻擊者同樣可以攻擊一些舊版本的 SSL/TLS 協議。這其中就包括 SSL 3.0。

什麼是 HTTPS 降級攻擊

因為瀏覽器的相容性問題,當瀏覽器進行 HTTPS 連線失敗的時候,將會嘗試使用舊的協議版本,於是加密協議由更加安全的協議,比如 TLS 1.2 降級成 SSL 3.0。因此,在 HTTPS 降級攻擊中,攻擊者利用舊版本的 SSL/TLS 協議的漏洞,其中包括 SSL 3.0 的漏洞,然後攻擊者獲取安全連線當中某些可以降級成 SSL 3.0 的加密後的明文的通訊內容進行攻擊。

注意的是,如果伺服器支援 SSL 3.0 協議,同時,攻擊者又能作為中間人控制瀏覽器發起漏洞版本的 HTTPS 請求,此時,雖然攻擊者竊聽到加密的通訊內容,但加密的協議存在漏洞,可以進行降級攻擊,解密這些加密的通訊內容可以獲取有價值的資訊,例如使用者的隱私資料。

HTTPS 降級攻擊的解決之道

目前,解決 HTTPS 降級攻擊的唯一方法是禁用 SSL 3.0 協議,並防止 TLS 1.2 協議、 TLS 1.1 協議與 TLS 1.0 協議降級到 SSL 3.0 協議。其中,禁用 SSL 3.0 協議的策略有很多,這裡主要介紹下 Nginx 如何防止 TLS 1.2 協議、 TLS 1.1 協議與 TLS 1.0 協議降級到 SSL 3.0 協議以下版本,從而防止 HTTPS 降級攻擊。

Nginx 原先的配置,如下所示。此時,如果 Nginx 原先的配置沒有額外的配置,那麼在 Nginx 中隱性預設是 SSLv3 TLSv1 TLSv1.1 TLSv1.2。

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
複製程式碼

Nginx 禁用 SSL 3.0 協議,並防止 TLS 1.2 協議、 TLS 1.1 協議與 TLS 1.0 協議降級到 SSL 3.0 協議的配置非常簡單,只需要遮蔽 SSLv3 引數即可,如下所示。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
複製程式碼

總結下,HTTPS 能確保通訊內容的安全傳輸嗎?答案是不一定,因為設計與實現 SSL/TLS 協議出現了漏洞,導致攻擊者同樣可以攻擊一些舊版本的 SSL/TLS 協議,其中就包括 SSL 3.0,可能會被攻擊者進行 HTTPS 的降級攻擊。因此,SSL 3.0 協議並不安全,為了防止 HTTPS 的降級攻擊,需要禁用 SSL 3.0 協議,確保TLS 1.2 協議、 TLS 1.1 協議與 TLS 1.0 協議降級到 SSL 3.0 協議以下版本。

(完)

更多精彩文章,盡在「服務端思維」微信公眾號!

來源:https://juejin.im/post/5951917af265da6c28109b84#comment

相關文章