https接密方式

原文鏈接:https://www.cnblogs.com/sddai/p/7612841.html

Web 安全是一項系統工程,任何細微疏忽都可能導致整個安全壁壘土崩瓦解。拿 HTTPS 來說,它的「內容加密、數據完整性、身份認證」三大安全保證,也會受到非法根證書、服務端配置錯誤、SSL 庫漏洞、私鑰被盜等等風險的影響。很多同學認爲只要訪問的網站地址前有一把小綠鎖就絕對安全,其實不然。本文通過介紹三種最常規的 HTTPS 流量解密方法及原理,淺談一下 HTTPS 的安全風險。

Man-in-the-middle

Man-in-the-middle(中間人,簡稱爲 MITM),能夠與網絡通訊兩端分別創建連接,交換其收到的數據,使得通訊兩端都認爲自己直接與對方對話,事實上整個會話都被中間人所控制。簡而言之,在真正的服務端看來,中間人是客戶端;而真正的客戶端會認爲中間人是服務端。

實現中間人攻擊有各種各樣的手段,這裏不展開討論。一些常見的 HTTP/HTTPS 抓包調試工具,都是通過創建本地 Proxy 服務,再修改瀏覽器 Proxy 設置來達到攔截流量的目的,他們的工作原理與中間人攻擊一致。我用過的這一類工具有:FiddlerCharles 和 whistle。我在「HTTP 代理原理及實現(一)」一文中介紹的 HTTP 普通代理,扮演的就是 HTTP 中間人角色。

本文主要討論 HTTPS 中間人,簡單示意如下:

Server <---> Local Proxy <---> Browser
         ^                 ^
       HTTPS(1)          HTTPS(2)

上述 HTTPS(1) 連接,是中間人冒充客戶端,與服務端建立的連接,由於 HTTPS 服務端一般不認證客戶端身份,這一步通常沒有問題。而對於 HTTPS(2) 連接來說,中間人想要冒充服務端,必須擁有對應域名的證書私鑰,而攻擊者要拿到私鑰,只能通過這些手段:

  1. 去網站服務器上拿;
  2. 從 CA 處簽發證書;
  3. 自己簽發證書。

要防範前兩點,需要網站做好各個方面的安全防護,從主機安全到網站安全(避免私鑰被盜),從域名解析安全到域名郵箱安全(避免攻擊者重簽證書)。而攻擊者自己簽發的證書,無法通過系統內置根證書的驗證,默認無法用於中間人攻擊。

對於 Fiddler 這一類調試工具來說,能夠解密 HTTPS 流量的關鍵在於他們會往系統受信任的根證書列表導入自己的證書,這樣他們的自簽證書就能被瀏覽器信任。進入 Fiddler 設置中的「HTTPS」Tab,勾選相關功能後,就可以順利解密和修改 HTTPS 流量。這時在瀏覽器中可以看到這樣的證書鏈:

 

RSA Private Key

我在「使用 Wireshark 調試 HTTP/2 流量」這篇文章中寫到:Wireshark 的抓包原理是直接讀取並分析網卡數據,要想讓它解密 HTTPS 流量,有兩個辦法:

  1. 如果你擁有 HTTPS 網站的加密私鑰,可以用來解密這個網站的加密流量;
  2. 某些瀏覽器支持將 TLS 會話中使用的對稱密鑰保存在外部文件中,可供 Wireshark 加密使用。

那篇文章介紹了第二種方案,本文簡單介紹第一種。

打開 Wireshark 的 SSL 協議設置,參考下圖,把 IP、端口、協議和證書私鑰都配上(私鑰必須存爲 PEM 格式):

然後訪問私鑰對應的網站,可以看到流量已被解密:

截圖中的加密數據是以 HTTP/1 傳輸的,這種方式能解密 HTTP/2 流量嗎?結論是:不能!具體原因下面慢慢分析。

我們知道,TLS 握手階段需要進行密鑰交換和服務端認證這兩個重要的操作,密鑰交換是爲了在不安全數據通道中產生一個只有通信雙方知道的共享密鑰 Premaster Secret,進而生成 Master Secret 以及後續對稱加密 Session Key 和 MAC Key。而客戶端進行服務端認證的目的是確保連接到擁有網站私鑰的合法服務器。

最常見的密鑰交換方式是 RSA,下面這張圖清晰的描述了這個過程:

Client Random 和 Server Random 明文傳輸,中間人可以直接查看。客戶端生成 Premaster Secret 後,用服務端證書公鑰加密後發送,如果服務端擁有對應的私鑰,就可以成功解密得到 Premaster Secret。這時,客戶端和服務端擁有相同的 Client Random、Server Random 和 Premaster Secret,可以各自算出相同的後續所需 Key。

可以看到,這種方式合併了密鑰交換和服務端認證兩個步驟,如果服務端能解密 Premaster Secret,也就意味着服務端擁有正確的私鑰。中間人沒有私鑰,無法得到 Premaster Secret,也就無法解密後續流量。

對於 Wireshark 來說,配置某個網站的私鑰後,能解密這個網站「使用 RSA 進行密鑰交換」的加密流量就很容易理解了。

顯然,RSA 密鑰交換有一個很大的問題:沒有前向安全性Forward Secrecy。這意味着攻擊者可以把監聽到的加密流量先存起來,後續一旦拿到了私鑰,之前所有流量都可以成功解密。

實際上,目前大部分 HTTPS 流量用的都是 ECDHE 密鑰交換。ECDHE 是使用橢圓曲線(ECC)的 DH(Diffie-Hellman)算法。下圖是 DH 密鑰交換過程:

上圖中的 Server DH Parameter 是用證書私鑰簽名的,客戶端使用證書公鑰就可以驗證服務端合法性。相比 RSA 密鑰交換,DH 由傳遞 Premaster Scret 變成了傳遞 DH 算法所需的 Parameter,然後雙方各自算出 Premaster Secret。

對於這種情況,由於 Premaster Secret 無需交換,中間人就算有私鑰也無法獲得 Premaster Secret 和 Master Secret。也就是說 Wireshark 無法通過配置 RSA Private Key 的方式解密「使用 ECDHE 進行密鑰交換」的加密流量。當然,使用 ECDHE 後,雖然中間人拿到私鑰也無法解密之前的流量,但他可以實施 MITM 攻擊來解密之後的流量,所以私鑰還是要保管好。

相比 RSA 既可以用於密鑰交換,又可以用於數字簽名;ECC 這邊就分得比較清楚了:ECDHE 用於密鑰交換,ECDSA 用於數字簽名。也就是目前密鑰交換 + 簽名有三種主流選擇:

  • RSA 密鑰交換、RSA 數字簽名;
  • ECDHE 密鑰交換、RSA 數字簽名;
  • ECDHE 密鑰交換、ECDSA 數字簽名;

以下是使用這三種密鑰交換方式的網站在 Chrome 中的截圖:

 

key exchange

HTTP/2 中只能使用 TLSv1.2+,還禁用了幾百種 CipherSuite(詳見:TLS 1.2 Cipher Suite Black List)。實際上,HTTP/2 允許使用的 CipherSuite 必須採用具有前向安全性的密鑰交換算法,不允許使用 RSA 密鑰交換。這也是爲什麼 RSA Private Key 無法解密 HTTP/2 加密流量。

SSLKEYLOGFILE

Firefox 和 Chrome 都會在系統環境變量存在 SSLKEYLOGFILE 文件路徑時,將每個 HTTPS 連接產生的 Premaster Secret 或 Master Secret 存下來。有了這個文件,Wireshark 就可以輕鬆解密 HTTPS 流量,即使是使用了 ECDHE 這種具有前向安全性的密鑰交換,如下圖:

 

decrypt http2 over tls

這種方案的詳細介紹請參考「使用 Wireshark 調試 HTTP/2 流量」這篇文章。

SSLKEYLOGFILE 文件記錄的是 HTTPS 數據傳輸中最重要的加密信息,如果不是出於調試目的,一般也沒人會主動配置這個環境變量,所以這個方案基本不會對 HTTPS 安全性產生影響。

總結

Fiddler 這類工具通過往系統導入根證書來實現 HTTPS 流量解密,充當中間人角色。要防範真正的 HTTPS 中間人攻擊,網站方需要保管好自己的證書私鑰和域名認證信息,爲了防範不良 CA 非法向第三方簽發自己的網站證書,還要儘可能啓用 Certificate TransparencyHTTP Public Key Pinning 等策略;用戶方不要隨便信任來歷不明的證書,更不要隨意導入證書到根證書列表,還要養成經常檢查常用網站證書鏈的習慣。

RSA 密鑰交換沒有前向安全性,這意味着一旦私鑰泄漏,之前所有加密流量都可以解開。爲此,網站方需要啓用使用 ECDHE 作爲密鑰交換的 CipherSuite,或者直接使用 ECC 證書;用戶方需要棄用不支持 ECDHE 的古董操作系統及瀏覽器。

對於瀏覽器而言,HTTPS 毫無祕密,通過瀏覽器生成的 SSLKEYLOGFILE 文件,Wireshark 可以輕鬆解密 HTTPS 流量。另外,如果瀏覽器被安裝惡意擴展,即使訪問安全的 HTTPS 網站,提交的數據一樣可以被截獲。這種客戶端被攻擊者控制引發的安全問題,無法通過 HTTPS 來解決。

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