申請正式SSL憑證是要花錢的,在測試網站SSL連線或僅作內部應用時,我們常會用SelfSSL工具或是Certificate Service自己搞一張SSL憑證自嗨一番,反正一樣可以做到傳輸加密的效果。另外,還有一種狀況是網站雖有正式SSL憑證,但註冊的是外部DNS名稱,在內網必須用IP存取網站,此時也會出現URL與SSL註冊對象不同的情形。

當上述情境中,DIY憑證或外部用憑證會被瀏覽器識破,彈出警告訊息:

在瀏覽器上可以選擇無視憑證不符的瑕疵,繼續使用。但若問題發生在WebClient用https存取網站時,就沒這麼幸運了,例如:

排版顯示純文字
WebClient wc = new WebClient();
string s = wc.DownloadString("https://192.168.1.1/Page.aspx");

沒有意外的話,你會得到以下訊息:

The underlying connection was closed: Could not establish trust relationship for SSL/TLS secure channel
(中文版為: 基礎連接已關閉: 無法為 SSL/TLS 安全通道建立信任關係。)

原本以為很難解的問題,沒想到只要加一行指令就搞定了!
(註: 以下簡易做法限用於WebClient只存取已知安全的網站時,一般狀況並不宜貿然關掉預設防護機制)

排版顯示純文字
WebClient wc = new WebClient();
ServicePointManager.ServerCertificateValidationCallback = 
                    delegate { return true; };
string s = wc.DownloadString("https://192.168.1.1/Page.aspx");

Comments

# by Michael

Great! Thanks!

# by 阀手动

的首发式地方

# by 麵包

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 是暫時性的關掉預設防護機制,那需要再打開嗎? 如果沒有是否對網頁或伺服器有其他隱憂? 如果需要,是同樣的程式,只是改成false嗎?ServicePointManager.ServerCertificateValidationCallback = delegate { return false; };

# by Jeffrey

to 麵包, 風險是「加上 return true 的程式將不檢查 SSL 憑證是否有效」,影響範圍僅限有修改 ServicePointManager.ServerCertificateValidationCallback 的程式,其他程式會依預設值檢查 HTTPS 連線憑證合法性。 不檢查憑證合法性的隱憂是無法偵測網路環境是否被人動手腳,有可能被駭客以中間人手法竊聽 HTTPS 傳輸內容。所以原則是非必要不要覆寫ServerCertificateValidationCallback設定,其餘時候什麼都不要做,預設值本身就是安全的。

# by 麵包

To Jeffrey,非常感謝您的解答。 我想再詢問一個問題,關於影響範圍,指的是該支Controller嗎?假如我是在Controller或者是Model裡面加入此程式,那至下一個Controller或者Model,ServerCertificateValidationCallback的設定會自動回預設值嗎?

# by Jeffrey

to 麵包,ServicePointManager.ServerCertificateValidationCallback 為靜態屬性,影響範圍為整個 Process (ASP.NET Application),不只單一 Controller,改完了也不會自動恢復預設值,要不影響到其他 Controller 有點困難。

# by 麵包

To Jeffrey,謝謝您的詳細回答,真的是讓我受益良多。

Post a comment