2010-04-20 192 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); 
}