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.
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.