Search code examples
c#sslhttpwebrequestclient-certificates

Certificate Authentication fails with SSL error in .Net only


I'm trying to communicate with an external website using mutual certificate authentication, but am receiving a "Could not establish secure channel for SSL/TLS with authority" exception. I've narrowed it down to the following snippet (sensitive things removed):

void Example() 
{
                string KeyIdentifier = "<MyKeyId>";

                X509Store store = new X509Store("My", StoreLocation.LocalMachine);
                store.Open(OpenFlags.ReadOnly);

                X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, KeyIdentifier, true);
                X509Certificate2 certificate = certificates[0];

                HttpWebRequest r = (HttpWebRequest)HttpWebRequest.Create("https://www.example.org");
                r.ClientCertificates.Add( certificate);

                r.Accept = "text/xml";
                r.Method = WebRequestMethods.Http.Post;

                string result = null;
                using (HttpWebResponse resp = (HttpWebResponse)r.GetResponse())
                {
                    StreamReader reader = new StreamReader(resp.GetResponseStream());
                    result = reader.ReadToEnd();
                }
}

I've set up the certificates and such properly and this code finds them successfully, with certificate.HasPrivateKey=true, but fails. SoapUI happily connects with TLS. Chrome reports no certificate errors when I access the website. However, the above code always throws the exception. I've tried all 3 TLS versions with no success. Using ServicePointManager to skip server Cert validation makes no difference.

Strangely, if I specify SSL3

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

then the process completes successfully, but naturally I don't want to be using SSL3. The app is .Net 4.6 running on Server 2012.


Solution

  • After several months and more digging on and off I ended up trying to make the connection using SSLStream, getting a different exception, and finding this answer: A call to SSPI failed, see inner exception - The Local Security Authority cannot be contacted

    which advises you to add the following registry key: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman] "ClientMinKeyBitLength"=dword:00000200

    This switches the minimum key length for Diffie-Hellman to 512-bit. This minimum value was raised in a Windows Update to 1024-bit to attempt to mitigate logjam attacks, so take care in setting this value as it is system wide and may open up attack vectors against your system.