如何使用 RSA 非同步加密通過 Wireshark 解密 TLS 流量?
我希望能夠擷取和解密我的內部應用程序(我無權訪問)對網際網路產生的 TLS 流量。(為了測試,我正在使用 Postman 創建對安全伺服器的請求。)
- 我所做的是添加一個 Nginx 作為反向代理。
- 我使用下一個命令創建了一個自簽名證書:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt
- 我將 ssl 配置添加到 /etc/nginx/sites-enabled/default 文件中的證書。
server { # SSL configuration # listen 443 ssl default_server; ssl_certificate /home/mavi/nginx/keys/localhost.crt; ssl_certificate_key /home/mavi/nginx/keys/localhost.key; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. #try_files $uri $uri/ =404; proxy_pass https://myService.com; proxy_http_version 1.1; } }
- 我在 Wireshark Edit> Preferences > SSL > RSA Keys list中添加了使用 OpenSSL 生成的密鑰。
- 我創建了指向我的代理 (HTTPS://127.0.0.1) 的請求,並將請求重定向到外部服務,我得到了正確的響應。
如果我使用 RSA 密鑰交換,為什麼我無法解密數據?
我一直在調查(如果我錯了,請糾正我)非同步加密的類型。我知道 RSA 將帶有證書的公鑰發送給客戶端,然後客戶端使用這個公鑰來加密數據。然後當這個加密的數據被發送到伺服器時,它使用私鑰來解密資訊。所以如果我在 Wireshark 中使用這個私鑰,我應該能夠解密數據,對吧?
另外,我讀到為了安全起見,我們已經停止使用 RSA,現在我們轉而使用 Diffie Hellman 算法(ECDH、ECDHE DFH)。Diffie Hellman 及其變體不再使用私鑰,它使用保存在 RAM 中的隨機會話密鑰。(作為解密 Diffie Hellman 包的註釋,我們需要在系統 $SSLKEYLOGFILE 中添加一個全域變數並將此文件導入 Wireshark。這僅適用於 Google Chrome、Firefox、CURL,不適用於內部應用程序)
所以我認為這就是我無法解密數據的原因。因為在我的客戶端和我的伺服器(都在我的本地電腦中)的密碼協商中,即使我創建了 RSA 證書,也使用 Diffie Hellman 作為非同步加密。我猜他們正在使用 Diffie Hellman,因為在 TLS 握手中我看到他們同意使用 0xc030
如果我是對的,那麼我應該將我的問題更改為如何指定要在 Nginx 配置中使用的密碼? 現在我的 Nginx 開啟了 ssl_prefer_server_ciphers;配置。
我將添加 TLS 握手,以便您可以看到密碼的協商。客戶您好
伺服器你好
正如我猜測的那樣,問題出在伺服器和客戶端同意的密碼中。
**如果 RSA 密鑰用於加密數據,我們只能解密 TLS/SSL 數據包數據。**如果使用 Diffie-Hellman Ephemeral (DHE) 或 RSA 臨時密碼套件,則 RSA 密鑰僅用於保護 DH 或 RSA 交換,而不是加密數據。因此,即使您擁有正確的 RSA 私鑰,您也無法使用 ssldump、Wireshark 或任何其他工具解密數據。您可以通過檢查持有私鑰的主機發送的 Server Hello 數據包來檢查正在使用哪個密碼套件,如果指定的密碼套件以 TLS_DHE 或 SSL_DHE 開頭,您將無法解密數據。如果伺服器發送 ServerKeyExchange 消息,您將無法解密數據。對於 DHE,您唯一的選擇(如果可能)是修改客戶端或伺服器配置,以便不使用 DHE 密碼套件。
ECDHE 或 DH (Diffie-Hellman) 都創建只有 SSL 連接中涉及的實體才能訪問的會話密鑰。因為會話密鑰沒有連結到伺服器的密鑰對,伺服器的私鑰不能單獨用於解密任何 SSL 會話。
所有 TLS_RSA 密碼套件都被標記為 WEAK,因為它們不提供前向保密,這意味著在 TLS_RSA 中,私鑰用於解密數據:如果私鑰在未來被洩露,所有記錄的流量都可以使用它來解密.
現在回答我自己的問題:如何指定要在 Nginx 配置中使用的密碼?
我必須將我的 Nginx 伺服器配置為僅在 /etc/nginx/nginx.conf 文件中使用 TLS_RSA 密碼
http { ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ssl_ciphers AES256-SHA256:AES256-SHA:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:DES-CBC3-SHA; }
這樣我就可以解密數據。正如我們在下圖中看到的,客戶端和伺服器同意使用 TLS_RSA_WITH_AES_256_CBC_SHA(0X0035),Wireshark 可以使用私鑰解密數據。
帶有 ECDHE-RSA-AES256-GCM-SHA384 的 TLS 1.2 具有前向保密性。請注意它出現在Mozilla 密碼列表的中間級別。無法僅使用伺服器密鑰進行解密是一項功能。
也提取客戶端密鑰。由於這會終止 nginx 上的 TLS,因此請獲取 nginx 的客戶端密鑰。沒有任何簡單的選項來啟用它,編譯和載入你自己的鉤子。例如,請參閱從 nginx 中提取 openssl pre-master secret,它使用某人的sslkeylog.c。因為 OpenSSL 的 keylog API 是已知的,所以這樣的庫適用於任何客戶端,包括帶有 OpenSSL 的 nginx。
像往常一樣,在編譯第三方程式碼時要注意安全和操作問題。如果不需要 nginx,請考慮其他一些代理,其中鍵日誌記錄是mitmproxy之類的功能