2010-06-23 147 views
7

向遠程Web服務器發出HTTPS請求時,我使用WebRequest,它建立與遠程Web服務器的安全連接。在開發過程中,我使用服務器上的自簽名證書,並且WebRequest無法建立安全連接,因爲證書無效,這是預期的行爲。在HTTPS請求期間驗證遠程SSL證書

我發現此代碼「遠程」證書檢查,通過在以下代碼中調用SetCertificatePolicy()方法來激活。

public static void SetCertificatePolicy() 
{ 
    ServicePointManager.ServerCertificateValidationCallback 
       += RemoteCertificateValidate; 
} 

/// <summary> 
/// Remotes the certificate validate. 
/// </summary> 
private static bool RemoteCertificateValidate(
    object sender, X509Certificate cert, 
    X509Chain chain, SslPolicyErrors error) 
{ 
    // trust any certificate!!! 
    System.Console.WriteLine("Warning, trust any certificate"); 
    return true; 
} 

我想知道,如果它是可以做到遠程SSL證書專項檢查(使用上面的代碼,例如),這樣我就可以驗證遠程Web服務器使用有效的SSL證書,而不是任何有效的證書,但恰恰是我想要的證書?例如,我想確保我正在與www.someplace.com網站交談,向ACME公司頒發證書,指紋00:11:22:.....

什麼是「最佳實踐「這種情況下的方法?

謝謝!

回答

7

如果您確實想要將其指定爲一個特定的證書,您可以將證書數據(DER格式)與certificate.GetRawCertData()中的byte[]進行比較。

您還可以使用GetCertHashString()SubjectRemoteCertificateValidate中的certificate參數進行獲取。主機名稱應該在證書的主題備選名稱中,或者如果主題(專有名稱)的CN中沒有主題備選名稱。考慮到.NET格式化主題字符串的方式,這應該是您在那裏找到的第一個CN =。

如果certificateX509Certificate2的實例,那麼您還將獲得更多數據。然後,您將能夠獲得SubjectName作爲X500PrincipalName以及Extensions(以檢查主題替代名稱擴展名)。使用諸如BouncyCastle之類的工具來解析主題名稱可能很有用。

根據運行時類型的不同,您也可能會獲得更多有關您嘗試聯繫sender中的主機名的信息。

+0

謝謝,那正是我所尋找的信息。關於第一個提示(比較證書數據與byte []),我需要比較已知的有效證書的字節數組和我正在驗證的字節數組嗎? – 2010-06-23 16:53:07

+0

我認爲字節數組將會是DER編碼中的證書,因此您應該將其與DER格式的參考證書(許多工具,包括Windows證書工具可以導出爲該格式)進行比較。你甚至可以直接從證書庫中加載(不知道如何)。 – Bruno 2010-06-23 17:29:28