.NET 連 HTTPS 網站「基礎連接已關閉」之 Windows 版本問題
6 |
幫忙查問題遇到第三次,依慣例已達專門為它寫篇文章的門檻。
案例一,.NET 呼叫 URL,在本機測試 OK,移至目標主機後程式冒出「基礎連接已關閉」錯誤(詳細訊息在下面),這個錯誤最典型的原因是 .NET 未啟用 TLS1.2 支援,但確認程式有明確指定 TLS 1.2;同一時間,該主機上另有 Python 程式連相同 URL 未遇到問題。
案例二,Chrome、Python 可以但 IE11、.NET 程式無法連線的 TLS 1.2 網站
案例三,某個連接特定網站的 .NET 排程已運作多年,近期目標網站換版升級,之後排程便出現「基礎連接已關閉」錯誤。使用 openssl s_client -tls1_X 測試確認網站同時支援 TLS 1.0/1.1/1.2,可排除升級後只限定 TLS 1.2 造成。
基礎連接已關閉: 傳送時發生未預期的錯誤。 ---> System.IO.IOException: 驗證失敗,因為遠端群體已經關閉傳輸資料流。 The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream
直接說答案 - Windows 版本太舊,不支援新版 Cipher Suite。三個案例的狀況都是目標網站基於安全改用 ECDHE-RSA-AES128-GCM-SHA256 (稱為 Cipher Suite,TLS 加密的金鑰交換、數位簽章、資料傳輸對稱式加密、訊息驗證的各環節各有多種標準可選,可想成「凱薩沙拉 + 羅宋湯 + 乾煎櫻桃鴨胸佐紅酒醬 + 焦糖烤布蕾」的點餐組合概念 參考),而不同版本 Windows 可支援的 Cipher Suite 不同。像是 Windows 2012R2 就不支援 ECDHE-RSA-AES128-GCM-SHA256,要到 Windows 2016/Windows 10 v1511 才支援,而上述案例的 Windows OS 版本分別為 Win 2012R2、Win 2012R2、Win 2008 (嘩...)。
整理一下判斷及處理 Windows TLS 相容問題的 SOP:
- 檢查網站支援的 TLS 版本及 Cipher Suite 項目。若為 Internet 公開網站,可使用 SSL Labs 的 SSL Server Test 參考;非公開站台則可考慮
nmap -p 443 --script ssl-enum-ciphers <host>
(需另外下載安裝 nmap,但 nmap 因功能強大連駭客也愛用,在某些資安規範被列為管制軟體,在企業內部可能驚動資安被請去喝咖啡) 一次列舉 TLS 及 Cipher Suite 清單。
若不用 nmap,可參考保哥這篇:使用 OpenSSL 與 cURL 檢查網站伺服器支援哪幾種 Cipher Suites,先用openssl ciphers
列舉可用 Cipher Suite,再配合 curl 逐一測試是否支援。(使用 Git Bash 跑批次)
- 若 Cipher Suite 如 ECDHE-RSA-AES128-GCM-SHA256 有 GCM,而你的 Windows 版本小於 Windows 2016 (Windows 2008R2、Winows 2012、Windows 2012R2),對 IE、.NET 程式基本上無解。
其他 Cipher Suite 及 Windows 版本,可參考這篇:Cipher Suites in TLS/SSL (Schannel SSP) 及 Windows 各版本支援 - 額外佐證:相同 .NET 程式在新一點的 Windows 跑沒問題、舊版 Windows 上跑 Chrome、Python、curl 也沒問題,就 IE 及 .NET 程式不行。若有前述狀況,亦可佐證是 Windows 不支援 Cipher Suite 造成。
- 以上過時 Windows 中最晚的 2012R2 也將 EOS,故升級新版 Windows 為正解。若有苦衷作業系統暫無法升級,可考慮替代方案:改用 curl、Chrome、Python 或其他使用 OpenSSL 程式庫的工具。
Case of .NET program failed to connect HTTPS web becaused of expired Windows version.
Comments
# by 南無阿彌陀佛
對本上對 IE、.NET 程式來說無解。 基本上對 IE、.NET 程式來說無解。
# by Jeffrey
to 南無阿彌陀佛,已修正。(合十)
# by Jekyll
內部網站可以考慮用這個. https://testssl.sh/
# by Jeffrey
to Jekyll, 感謝分享。(可惜 testssl.sh 不直接支援 Windows)
# by Walkman
以下句子出現兩次Win 2012R2,是否其中一個應該是Win 2012呢? 而上述案例的 Windows OS 版本分別為 Win 2012R2、Win 2012R2、Win 2008 (嘩...)。
# by Jeffrey
Walkman,總共在三台機器上遇到,前兩台都是 Win2012R2。