三種解密 HTTPS 流量的方法介紹

 

轉載自:https://imququ.com/post/how-to-decrypt-https.html做者: Jerry Qu
html

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

Man-in-the-middle

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

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

本文主要討論 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 加密使用。

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

打開 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

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

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 來解決。

相關文章
相關標籤/搜索