How to solve "Could not establish trust relationship for the SSL/TLS secure channel with authority"

.NetWcfIisCertificate

.Net Problem Overview


I have a WCF service hosted in IIS 7 using HTTPS. When I browse to this site in Internet Explorer, it works like a charm, this is because I have added the certificate to the local root certificate authority store.

I'm developing on 1 machine, so client and server are same machine. The certificate is self-signed directly from IIS 7 management snap in.

I continually get this error now...

> Could not establish trust relationship for the SSL/TLS secure channel with authority.

... when called from client console.

I manually gave myself permissions and network service to the certificate, using findprivatekey and using cacls.exe.

I tried to connect to the service using SOAPUI, and that works, so it must be an issue in my client application, which is code based on what used to work with http.

Where else can I look I seem to have exhausted all possibilities as to why I can't connect?

.Net Solutions


Solution 1 - .Net

As a workaround you could add a handler to the ServicePointManager's ServerCertificateValidationCallback on the client side:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (se, cert, chain, sslerror) =>
        {
            return true;
        };

but be aware that this is not a good practice as it completely ignores the server certificate and tells the service point manager that whatever certificate is fine which can seriously compromise client security. You could refine this and do some custom checking (for certificate name, hash etc). at least you can circumvent problems during development when using test certificates.

Solution 2 - .Net

When I have this problem it is because the client.config had its endpoints like:

 https://myserver/myservice.svc 

but the certificate was expecting

 https://myserver.mydomain.com/myservice.svc

Changing the endpoints to match the FQDN of the server resolves my problem. I know this is not the only cause of this problem.

Solution 3 - .Net

Your problem arises because you're using a self signed key. The client does not trust this key, nor does the key itself provide a chain to validate or a certificate revocation list.

You have a few options - you can

  1. turn off certificate validation on the client (bad move, man in the middle attacks abound)

  2. use makecert to create a root CA and create certificates from that (ok move, but there is still no CRL)

  3. create an internal root CA using Windows Certificate Server or other PKI solution then trust that root cert (a bit of a pain to manage)

  4. purchase an SSL certificate from one of the trusted CAs (expensive)

Solution 4 - .Net

the first two use lambda, the third uses regular code... 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;
    }

Solution 5 - .Net

A one line solution. Add this anywhere before calling the server on the client side:

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

This should only be used for testing purposes because the client will skip SSL/TLS security checks.

Solution 6 - .Net

I encountered the same problem and I was able to resolve it with two solutions: First, I used the MMC snap-in "Certificates" for the "Computer account" and dragged the self-signed certificate into the "Trusted Root Certification Authorities" folder. This means the local computer (the one that generated the certificate) will now trust that certificate. Secondly I noticed that the certificate was generated for some internal computer name, but the web service was being accessed using another name. This caused a mismatch when validating the certificate. We generated the certificate for computer.operations.local, but accessed the web service using https://computer.internaldomain.companydomain.com. When we switched the URL to the one used to generate the certificate we got no more errors.

Maybe just switching URLs would have worked, but by making the certificate trusted you also avoid the red screen in Internet Explorer where it tells you it doesn't trust the certificate.

Solution 7 - .Net

If you use .net core try this:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
        };

Solution 8 - .Net

Please do following steps:

  1. Open service link in IE.

  2. Click on the certificate error mention in address bar and click on View certificates.

  3. Check issued to: name.

  4. Take the issued name and replace localhost mention in service and client endpoint base address name with A fully qualified domain name (FQDN).

For Example: https://localhost:203/SampleService.svc To https://INL-126166-.groupinfra.com:203/SampleService.svc

Solution 9 - .Net

In addition to the answers above, you could encounter this error if your client is running the wrong TLS version, for example if the server is only running TLS 1.2.

You can fix it by using:

// tested in .NET 4.5:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Solution 10 - .Net

I had the same problem. I also had added CA certificates in the local store, but I did in the WRONG way.

Using mmc Console (Start -> Run -> mmc ) you should add Certificates snap-in as Service account (choosing the service account of IIS) or Computer account (it adds for every account on the machine)

Here an image of what I'm talking about Add snap-in for a service account or the computer account

From here now, you can add certificates of CAs (Trusted Root CAs and Intermediate CAs), and everything will work fine

Solution 11 - .Net

I had similar issue with self-signed certificate. I could resolve it by using the certificate name same as FQDN of the server.

Ideally, SSL part should be managed at the server side. Client is not required to install any certificate for SSL. Also, some of the posts mentioned about bypassing the SSL from client code. But I totally disagree with that.

Solution 12 - .Net

I just dragged the certificate into the "Trusted Root Certification Authorities" folder and voila everything worked nicely.

Oh. And I first added the following from a Administrator Command Prompt:

netsh http add urlacl url=https://+:8732/Servicename user=NT-MYNDIGHET\INTERAKTIV

I am not sure of the name you need for the user (mine is norwegian as you can see !): user=NT-AUTHORITY/INTERACTIVE ?

You can see all existing urlacl's by issuing the command: netsh http show urlacl

Solution 13 - .Net

I just wanted to add something to the answer of @NMrt who already pointed out:

> you could encounter this error if your client is running the wrong TLS version, for example if the server is only running TLS 1.2.

With Framework 4.7.2, if you do not explicitly configure the target framework in your web.config like this

<system.web>
  <compilation targetFramework="4.7" />
  <httpRuntime targetFramework="4.7" />
</system.web>

your system default security protocols will be ignored and something "lower" might be used instead. In my case Ssl3/Tls instead of Tls13.

  • You can fix this also in code by setting the SecurityProtocol (keeps other protocols working):

    System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11;
    System.Net.ServicePointManager.SecurityProtocol &= ~System.Net.SecurityProtocolType.Ssl3;
    
  • or even by adding registry keys to enable or disable strong crypto

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
    "SchUseStrongCrypto"=dword:00000001
    

This blog post pointed me to the right direction and explains the backgrounds better than I can:

https://www.ryadel.com/en/asp-net-client-server-cannot-comunicate-because-they-possess-common-algorithm-how-to-fix-c-sharp/

Solution 14 - .Net

This occurred when trying to connect to the WCF Service via. the IP e.g. https://111.11.111.1:port/MyService.svc while using a certificate tied to a name e.g. mysite.com.

Switching to the https://mysite.com:port/MyService.svc resolved it.

Solution 15 - .Net

This occurred when trying to connect to the WCF Service using only host name e.g. https://host/MyService.svc while using a certificate tied to a name e.g. host.mysite.com.

Switching to the https://host.mysite.com/MyService.svc and this resolved it.

Solution 16 - .Net

Just fixed a similar issue.

I realized I had an application pool that was running under an account that only had reading permission over the certificate that it was used.

The .NET application could correctly retrieve the certificate but that exception was thrown only when GetRequestStream() was called.

Certificates permissions can be managed via MMC console

Solution 17 - .Net

If you are using .net core, then during development you can bypass certificate validation by using compiler directives. This way will only validate certificate for release and not for debug:

#if (DEBUG)
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck
                };   #endif

Solution 18 - .Net

Add this to your client code :

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJL.View Question on Stackoverflow
Solution 1 - .NetJoachim KerschbaumerView Answer on Stackoverflow
Solution 2 - .NetMike CheelView Answer on Stackoverflow
Solution 3 - .NetblowdartView Answer on Stackoverflow
Solution 4 - .NetSebastian CastaldiView Answer on Stackoverflow
Solution 5 - .NetGaspa79View Answer on Stackoverflow
Solution 6 - .NetJeroen-bart EngelenView Answer on Stackoverflow
Solution 7 - .NetGrzegorz JView Answer on Stackoverflow
Solution 8 - .NetRahul RaiView Answer on Stackoverflow
Solution 9 - .NetNMrtView Answer on Stackoverflow
Solution 10 - .Netdar0xView Answer on Stackoverflow
Solution 11 - .NetUmesh BhavsarView Answer on Stackoverflow
Solution 12 - .NetHagunaView Answer on Stackoverflow
Solution 13 - .NetphifiView Answer on Stackoverflow
Solution 14 - .NetlkoView Answer on Stackoverflow
Solution 15 - .NetsoniaView Answer on Stackoverflow
Solution 16 - .NetAlbertoView Answer on Stackoverflow
Solution 17 - .NetPanayiotis HiripisView Answer on Stackoverflow
Solution 18 - .NetBokamboView Answer on Stackoverflow