Could not establish trust relationship for SSL/TLS

2018-12-31 21:21发布

I have a simple web service call, generated by a .NET (C#) 2.0 windows app, via the web service proxy generated by Visual Studio, for a web service also written in C# (2.0). This has worked for several years, and continues to do so at the dozen or so places where it is running.

A new installation at a new site is running into a problem. When attempting to invoke the web service, it fails with the message saying:

Could not establish a trust relationship for the SSL/TLS secure channel

The URL of the web service uses SSL (https://) -- but this has been working for a long time (and continues to do so) from many other locations.

Where do I look? Could this be a security issue between Windows and .NET that is unique to this install? If so, where do I set up trust relationships? I'm lost!

标签: c# .net ssl trust
15条回答
看风景的人
2楼-- · 2018-12-31 21:45

In my case I was trying to test SSL in my Visual Studio environment using IIS 7.

This is what I ended up doing to get it to work:

  • Under my site in the 'Bindings...' section on the right in IIS, I had to add the 'https' binding to port 443 and select "IIS Express Developement Certificate".

  • Under my site in the 'Advanced Settings...' section on the right I had to change the 'Enabled Protocols' from "http" to "https".

  • Under the 'SSL Settings' icon I selected 'Accept' for client certificates.

  • Then I had to recycle the app pool.

  • I also had to import the local host certificate into my personal store using mmc.exe.

My web.config file was already configured correctly, so after I got all the above sorted out, I was able to continue my testing.

查看更多
听够珍惜
3楼-- · 2018-12-31 21:46

If you do not wan't to blindly trust everybody and make a trust exception only for certain hosts the following solution is more appropriate.

public static class Ssl
{
    private static readonly string[] TrustedHosts = new[] {
      "host1.domain.com", 
      "host2.domain.com"
    };

    public static void EnableTrustedHosts()
    {
      ServicePointManager.ServerCertificateValidationCallback = 
      (sender, certificate, chain, errors) =>
      {
        if (errors == SslPolicyErrors.None)
        {
          return true;
        }

        var request = sender as HttpWebRequest;
        if (request != null)
        {
          return TrustedHosts.Contains(request.RequestUri.Host);
        }

        return false;
      };
    }
}

Then just call Ssl.EnableTrustedHosts when your app starts.

查看更多
一个人的天荒地老
4楼-- · 2018-12-31 21:46

For those who are having this issue through a VS client side once successfully added a service reference and trying to execute the first call got this exception: “The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel” If you are using (like my case) an endpoint URL with the IP address and got this exception, then you should probably need to re-add the service reference doing this steps:

  • Open the endpoint URL on Internet Explorer.
  • Click on the certificate error (red icon in address bar)
  • Click on View certificates.
  • Grab the issued to: "name" and replace the IP address or whatever name we were using and getting the error for this "name".

Try again :). Thanks

查看更多
长期被迫恋爱
5楼-- · 2018-12-31 21:48

The following snippets will fix the case where there is something wrong with the SSL certificate on the server you are calling. For example, it may be self-signed or the host name between the certificate and the server may not match.

This is dangerous if you are calling a server outside of your direct control, since you can no longer be as sure that you are talking to the server you think you're connected to. However, if you are dealing with internal servers and getting a "correct" certificate is not practical, use the following to tell the web service to ignore the certificate problems and bravely soldier on.

The first two use lambda expressions, the third uses regular code. The first accepts any certificate. The last two at least check that the host name in the certificate is the one you expect.
... hope you find it helpful

//Trust all certificates
System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

// trust sender
System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

// validate cert by calling a function
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
    bool result = false;
    if (cert.Subject.ToUpper().Contains("YourServerName"))
    {
        result = true;
    }

    return result;
}
查看更多
千与千寻千般痛.
6楼-- · 2018-12-31 21:49

If not work bad sertificate, when ServerCertificateValidationCallback return true; My ServerCertificateValidationCallback code:

ServicePointManager.ServerCertificateValidationCallback += delegate
{
    LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback");
    return true;
};

My code which the prevented execute ServerCertificateValidationCallback:

     if (!(ServicePointManager.CertificatePolicy is CertificateValidation))
    {
        CertificateValidation certValidate = new CertificateValidation();
        certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError);
        ServicePointManager.CertificatePolicy = certValidate;
    }

OnValidateCertificateError function:

private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e)
{
    string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message);
    LogWriter.LogError(msg);
    //Message.ShowError(msg);
}

I disabled CertificateValidation code and ServerCertificateValidationCallback running very well

查看更多
君临天下
7楼-- · 2018-12-31 21:50

The very simple "catch all" solution is this:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

The solution from sebastian-castaldi is a bit more detailed.

查看更多
登录 后发表回答