2010-04-20 191 views
115

我是一個Web服務請求時收到以下錯誤遠程Web服務:C#忽略證書錯誤?

Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

反正有沒有忽略這個錯誤,並繼續嗎?

看來遠程證書沒有簽名。

我連接到的網站是www.czebox.cz - 所以請隨時訪問該網站,並通過安全例外通知瀏覽器。

回答

261

添加證書驗證處理程序。返回true將允許忽略驗證錯誤:

ServicePointManager 
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true; 
+5

這比起初可能會更有用。我在使用託管交換Web服務(EWS)的同時遇到了OP的問題。我以爲我不能使用這個答案,因爲我沒有訪問該託管庫正在進行的低級SOAP調用。但是當我再看看它時,我意識到ServicePointManager是獨立存在的。所以,我在初始化ExchangeService之前添加了上述回調函數,並且它像魅力一樣工作。 – 2012-04-19 21:50:39

+0

@PeterLillevold我有一個自簽名的SSL進行內部測試,據我所知,這忽略了錯誤,只是很難找到沒有指導! – Pogrindis 2015-07-14 22:45:12

+0

@Pogrindis - 是的,自簽名證書(因爲它本質上不是可信證書)不會通過證書驗證。在回調中返回'true'將忽略驗證錯誤,從而允許使用不可信證書完成對網站的調用。 – 2015-07-15 00:50:13

24

它的失敗的原因不是因爲它沒有簽名,但因爲根證書不是由您的客戶的信賴。與其關閉SSL驗證,另一種方法是將根CA證書添加到您的應用信任的CA列表中。

這根CA證書,您的應用目前不信任:

----- BEGIN CERTIFICATE ----- MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf 2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT + tVDTeUUjT133G 7Vs51D6z/ShWy + 9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH 0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2 + X3hXBfvRMr5l6zgxYVATEyxCfOLM9 a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz IWR + 3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC + gLYYraHR0 cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50 byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw + R + S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN 5OTjbpOTEEkq2jFI0tUhtRx // 6zwuqJCzfO/KqggUrHBca + GV/qXcNzNAlytyM71 FMV/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK /米+ IFfirxSRi8LRERdXHTEb vwxMXIzZVXloW vX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a + Y + z184UhuZ/oGyMw eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF Y + jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36 + NyEK/ts3mPLL

----- END CERTIFICATE -----

可以解碼並查看使用該證書

this certificate decoderanother certificate decoder

23

IgnoreBadCertificates方法:

//I use a method to ignore bad certs caused by misc errors 
IgnoreBadCertificates(); 

// after the Ignore call i can do what ever i want... 
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest; 

/* 
and below the Methods we are using... 
*/ 

/// <summary> 
/// Together with the AcceptAllCertifications method right 
/// below this causes to bypass errors caused by SLL-Errors. 
/// </summary> 
public static void IgnoreBadCertificates() 
{ 
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); 
} 

/// <summary> 
/// In Short: the Method solves the Problem of broken Certificates. 
/// Sometime when requesting Data and the sending Webserverconnection 
/// is based on a SSL Connection, an Error is caused by Servers whoes 
/// Certificate(s) have Errors. Like when the Cert is out of date 
/// and much more... So at this point when calling the method, 
/// this behaviour is prevented 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="certification"></param> 
/// <param name="chain"></param> 
/// <param name="sslPolicyErrors"></param> 
/// <returns>true</returns> 
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) 
{ 
    return true; 
} 
+1

我不得不再添加一行來讓它與我的代碼一起工作(我正在使用websocket4net)。 System.Net.ServicePointManager.CheckCertificateRevocationList = false; 設置服務器證書驗證回調之後。 – kalyanmysore 2016-02-04 21:19:49

+1

感謝您提供完整的代碼示例,該示例非常清晰,易於理解和實施。這應該是被接受的答案。 – Jake 2016-07-12 22:05:36

1

要在BIGNUM的後進一步擴大 - 在理想情況下,你想一個解決方案,將模擬你會在生產中查看和修改你的代碼不會做到這一點,可能是危險的,如果你忘記了之前採取的代碼的條件你部署它。

您需要某種自簽名證書。如果你知道你在做什麼,你可以使用二進制BIGNUM張貼,但如果不是,你可以去尋找證書。如果您使用的是IIS Express,則您將擁有其中一個,您只需要找到它即可。打開Firefox或任何你喜歡的瀏覽器並進入你的開發網站。您應該能夠從URL欄中查看證書信息,並且根據您的瀏覽器,您應該能夠將證書導出到文件。

接下來,打開MMC.exe,並添加證書管理單元。將您的證書文件導入受信任的根證書頒發機構存儲區,這就是您應該需要的一切。確保它進入該商店而不是像「個人」這樣的其他商店非常重要。如果您不熟悉MMC或證書,有許多網站會提供如何執行此操作的信息。

現在,您的計算機作爲一個整體將隱式地信任它自己生成的任何證書,並且您將不需要添加代碼來專門處理此問題。當您轉入生產環境時,只要您在那裏安裝了適當的有效證書,它就會繼續工作。不要在生產服務器上執行此操作 - 這會很糟糕,並且不適用於服務器本身以外的任何其他客戶端。

3

在客戶端配置中禁用ssl證書驗證。

<behaviors> 
    <endpointBehaviors> 
     <behavior name="DisableSSLCertificateValidation"> 
     <clientCredentials> 
      <serviceCertificate> 
       <sslCertificateAuthentication certificateValidationMode="None" /> 
       </serviceCertificate> 
      </clientCredentials> 
     </behavior> 
2

如果您直接使用套接字並正在作爲客戶端進行身份驗證,則Service Point Manager回調方法將不起作用。這是爲我工作的。 請僅用於測試目的

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; }); 
await activeStream.AuthenticateAsClientAsync("computer.local"); 

這裏的關鍵是在SSL流的構造函數中提供遠程證書驗證回調權限。

13

允許所有證書是非常強大的,但它也可能是危險的。如果您只想允許有效的證書和某些特定的證書,可以這樣做。

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender, 
    X509Certificate cert, 
    X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    { 
     return true; //Is valid 
    } 

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7") 
    { 
     return true; 
    } 

    return false; 
}; 

更新:

如何在Chrome中獲得cert.GetCertHashString()值:

在地址欄中點擊SecureNot Secure

enter image description here

enter image description here

然後點擊證書 - >詳細信息 - >指紋和複製的價值。記得做cert.GetCertHashString().ToLower()

enter image description here

+1

這應該是被接受的答案,只是多一點工作,但危險性要小得多。謝謝! – 2017-08-14 15:37:08

+2

@MiguelVeloso完全同意。這允許跳過檢查(希望)一個或兩個證書而不會完全危及安全。 – 2017-10-04 13:08:02

+0

你可以從cert獲得'Hash String'嗎? – Kiquenet 2018-03-05 09:52:53

1

此代碼爲我工作。我不得不添加TLS2,因爲這正是我感興趣的URL所使用的。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 
ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => { return true; }; 
using (var client = new HttpClient()) 
{ 
    client.BaseAddress = new Uri(UserDataUrl); 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new 
     MediaTypeWithQualityHeaderValue("application/json")); 
    Task<string> response = client.GetStringAsync(UserDataUrl); 
    response.Wait(); 

    if (response.Exception != null) 
    { 
     return null; 
    } 

    return JsonConvert.DeserializeObject<UserData>(response.Result); 
}