Client certificate not getting added to the request (Certificate Verify)

I have seen this same issue recently using .Net 4.7.2. In my case cert.HasPrivateKey would return true but cert.PrivateKey would return null. The fix was to export the certificate with private key as a pfx and then load it back into memory:

// Load the cert with private key
X509Certificate2 cert = ... 

// When the certificate is created, the private key is not associated with the object. In order
// for this to work correctly, we need to export it to a PFX and then re-import the cert.
byte[] certBytes = cert.Export(X509ContentType.Pfx);
cert = new X509Certificate2(certBytes);

After this the HttpClient would successfully send the cert to the server. Hope it helps.


While researching how to capture socket data to Wireshark, from my locally hosted page, I accidentally stumbled upon an article saying that "Certificate Verify" isn't sent over TLS 1.2 in "newer versions of Windows" (like Windows 10).

So I changed the protocol to TLS 1.0 and the request went through:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

With TLS 1.1 I get an exception, unlike what the guy in that article said:

(WebException) The request was aborted: Could not create SSL/TLS secure channel.

Why this worked isn't something I have time to investigate currently, as I'm already way behind schedule debugging this issue, but it sounds to me like a bug, much like another user claimed in another question.

I found a Microsoft article along these lines saying:

This issue only occurs with servers that downgrade the TLS session in an ungraceful way (such as by sending a TCP reset when receiving a TLS protocol version that the server does not support)

But since I start in TLS 1.2, and the server clearly accepts TLS 1.2 (via Postman and Chrome), it must be a tiny part of the TLS 1.2 protocol that isn't implemented the same way or something. I still don't understand how the Postman native Windows app manages to use TLS 1.2 though.

It may be worth noting that Internet Explorer first attempts TLS 1.2, and then after 2 resets (like my client), it just downgrades to TLS 1.0 and gets through. To me this sounds very similar to the update to Internet Explorer talked about in the article:

Wireshark showing IE resetting TLS 1.2 connection with Certificate Verify, and then downgrading to TLS 1.0


I realize this is not a great answer (when it comes to details of "why"), but at least it gives a hint as to what one might try if coming across similar issues.

If anyone understands this issue, and perhaps even knows how I can support TLS 1.2, then I'd appreciate it very much.