使用HttpWebRequest回報無法建立SSL/TLS的安全通道錯誤

今日電子郵件突然收到一支運作很穩定的程式(使用System.Net.HttpWebRequest)回報錯誤,看一下資料庫的Log得到「無法建立 SSL/TLS 的安全通道」,當下心底想的是可能被對方連接的伺服器婊了,馬上打開Google開始查詢,果不其然發現這個錯誤跟SSL 3.0協定廢止有很大的關係。

不爽的是,對方伺服器自己突然上patch導致Servlet停止支援某協定,是都不會講的喔!

HttpWebRequest引發的錯誤資訊如下所示

SecureChannelFailure
要求已經中止: 無法建立 SSL/TLS 的安全通道。
Cancelled the request: Unable to create a secure SSL/TLS channel.

ASP.NET解決停用SSL 3.0、TLS 1.0的方案

引發錯誤的原因是因為.NET Framework 1.1開始,就是都將SSL 3.0協定視為預設值,不料SSL 3.0在2014年被Google找出存在中間人攻擊的可能性(POODLEbleed),因此世界就開始慢慢地走向廢棄SSL 3.0的道路。然而,你以為你升級到.NET Framework他就會自動幫你調整到更安全的加密連線協定嗎?不,基於向下相容,依然是維持「Ssl3; Tls」的通訊協定,不信你把System.Net.ServicePointManager.SecurityProtocol將其值Get出來看便知道。(不然你也不會找到這個網頁)

方案其實有很多種,有改註冊表把整個Windows的連線環境調整成新協定的方式,也有利用程式碼進行全域宣告方式,基於偷懶的特性,我當然是採用程式碼的調用就可以了。SecurityProtocol是一個靜態屬性,在使用HttpWebRequest去進行GetResponse前,我們將其設定到TLS 1.2吧。

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

就這樣解完了,要注意的是SecurityProtocol是一個static,所以你一改全網站在Runtime執行期都會採用這個加密協定喔!當然如果你重開機就會不見。

最後文章附上註冊表式的解法,有興趣的可以看一下。(StackOverflow其實也有很多文章在討論)

(.NET) Enable SSL Protocols for your Integrations - TLS 1.1 and TLS 1.2 System.Net.HttpWebRequest System.Net.HttpWebResponse Error Fault SSL TLS