C#忽略证书错误?


159

在向远程Web服务发出Web服务请求期间,出现以下错误:

无法建立SSL / TLS安全通道的信任关系。---> System.Security.Authentication.AuthenticationException:根据验证过程,远程证书无效。

无论如何,有无视此错误并继续吗?

似乎远程证书未签名。

我连接到的站点是www.czebox.cz-可以随时访问该站点,并且甚至注意到浏览器也会抛出安全异常。

Answers:


341

添加证书验证处理程序。返回true将允许忽略验证错误:

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

6
这比起初看起来更有用。使用托管交换Web服务(EWS)时遇到了OP的问题。我以为我无法使用该答案,因为我无权访问该托管库发出的低级SOAP调用。但是,当我再次查看它时,我意识到ServicePointManager可以独立运行。因此,我在初始化ExchangeService之前添加了上述回调,它的工作原理很吸引人。
Mark Meuer

2
这是如何全局应用旁路的示例。为我们所有人陷入不良做法。(有时您别无选择)jasig.275507.n4.nabble.com/…–
snowYetis

1
非常感谢您暂时解决此问题。将此代码添加到Web Api的Startup.cs中
-Sivalingaamorthy

2
对于我的EWS API问题,@ MarkMeuer几乎要放弃此解决方案,但是后来我看到了您的评论。
马亨

7
@MiguelVeloso您可以随意投票,但是请记住,无论是问题还是答案都不会讨论此问题的安全性。主题明确地是“如何忽略验证错误”,而不是“为什么我们不应该这样做”,这是一个完全不同的主题。进入上为什么OP不应该这样做只会浑水摸鱼,作为评论者指出,有合理的情况下,你实际上是一个讨论做到这一点。因此,我们坚持主题并解决问题。
Peter Lillevold

40

允许所有证书非常强大,但这也很危险。如果您只想允许有效的证书加上某些证书,可以这样进行。

.Net核心:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };
    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

.Net框架:

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;
};

更新:

如何cert.GetCertHashString()在Chrome中获取价值:

单击SecureNot Secure在地址栏中。

在此处输入图片说明

在此处输入图片说明

然后单击证书->详细信息->指纹并复制该值。记住要做cert.GetCertHashString().ToLower()

在此处输入图片说明


3
@MiguelVeloso完全同意。这样可以跳过(希望)检查一个或两个证书,而不会完全损害安全性。
Kemuel Sanchez

我如何获得Hash String证书?
Kiquenet

@Kiquenet可以调试代码,然后cert.GetCertHashString()从浏览器中运行Immediate window或检查cert Thumbprint,或者MMC是否在本地安装了cert 。
Ogglas

服务器由我们控制,在生产中使用@Ogglas的代码仍然安全吗?使用TLS / SSL,可以阻止像中间人这样的攻击吗?
乒乓球

非常感谢您的帮助。
Wowo Ot

30

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;
} 

2
我必须再添加一行以使其与我的代码一起使用(我正在使用websocket4net)。System.Net.ServicePointManager.CheckCertificateRevocationList = false; 在设置服务器证书验证回调之后。
kalyanswaroop

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/m+IFfirxSRi8LRERdXHTEb
vwxMXIzZVXloWvX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a+y+z184UhuZ/oGyMw
eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF
Y+jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36+NyEK/ts3mPLL

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

您可以使用以下方法解码和查看此证书

此证书解码器其他证书解码器


是! 这是我的情况,但是如何在没有VM的情况下在Azure上添加证书?我可以只使用X509Store API吗?我要去尝试,明天但任何信息,欢迎在这里
若昂·安图内斯

7

在客户端配置中禁用ssl证书验证。

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

这是web.config吗?ASP.NET Core是否有替代方案?
Shimmy Weitzhandler,

5

这段代码对我有用。我必须添加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);
}

3

绕过SSL证书...

        HttpClientHandler clientHandler = new HttpClientHandler();
        clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

        // Pass the handler to httpclient(from you are calling api)
        var client = new HttpClient(clientHandler)

2

如果直接使用套接字并作为客户端进行身份验证,则Service Point Manager回调方法将不起作用。这是对我有用的东西。请仅用于测试目的

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

此处的关键是在SSL流的构造函数中提供远程证书验证回调。


1

要进一步扩展BIGNUM的职位,理想情况下,您需要一个能够模拟您在生产环境中会看到的条件的解决方案,并且修改代码不会这样做,并且如果您忘记在部署之前删除代码,可能会很危险。

您将需要某种自签名证书。如果您知道自己在做什么,则可以使用发布的二进制BIGNUM,但是如果不知道,可以使用证书。如果您使用的是IIS Express,那么您将已经拥有其中之一,只需找到它即可。打开Firefox或您喜欢的任何浏览器,然后转到开发人员网站。您应该能够从URL栏中查看证书信息,并且取决于浏览器,您应该能够将证书导出到文件中。

接下来,打开MMC.exe,并添加“证书”管理单元。将您的证书文件导入“受信任的根证书颁发机构”存储中,这就是您所需要的。重要的是要确保它进入该商店,而不是像“个人”这样的其他商店。如果您不熟悉MMC或证书,则有许多网站提供有关如何执行此操作的信息。

现在,您的计算机作为一个整体将隐式地信任它自己生成的任何证书,并且您无需添加代码来专门处理此证书。当您进入生产环境时,只要您在那里安装了正确的有效证书,它将继续工作。不要在生产服务器上执行此操作-这很不好,除了服务器本身上的其他客户端,其他客户端都无法使用。


1

这适用于.Net Core。致电您的Soap客户:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.