You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WebRequest/HttpClient客户端证书认证失败问题排查

Client Certificate Authentication Fails in C# HttpClient but Works with curl/openssl & SslStream

Background

Our client ran into client certificate authentication failures when using a C# HttpClient setup, even after properly configuring TLS 1.2 via IISCrypto—they disabled all SSL protocols and TLS 1.1, and set up the required cipher suites as specified.

Troubleshooting Journey

I started with a full round of standard checks to rule out common issues:

  • Verified cipher suite configurations matched the required specs
  • Confirmed .NET Framework version compatibility with TLS 1.2
  • Checked that Windows Server 2012 R2 (the client's OS) supported TLS 1.2
  • Investigated TLS renegotiation settings
  • Validated server certificate and API gateway configurations
  • Checked status of related Windows services

None of these steps uncovered the root cause. I even wrote a custom troubleshooting program to test the full communication and handshake flow, but still got no actionable leads.

The most confusing part? Requests sent via curl.exe and openssl s_client with the exact same client certificate succeeded, but the C# HttpClient code failed every time. Here's the failing HttpClient implementation:

X509Certificate2 cert = new X509Certificate2(@"C:\Communicate.pfx", "xxxxx");
HttpClient client = null;
System.Net.Http.WebRequestHandler _internalHandler = new System.Net.Http.WebRequestHandler();
_internalHandler.UseProxy = false;
_internalHandler.ClientCertificates.Add(cert);
_internalHandler.ServerCertificateValidationCallback = ((obj, x509, chain, policyError) => { return true; });
client = new HttpClient(_internalHandler);
client.BaseAddress = new Uri(string.Format("https://{0}:{1}/", args[0], int.Parse(args[1])));

Key Clash: SslStream Works Where HttpClient Doesn't

I then built a TCP test program using SslStream, which worked perfectly. This made it clear there was a fundamental difference in how HttpClient/WebRequest and SslStream handle client certificate selection. Here's the working SslStream code:

X509Certificate2 cert = new X509Certificate2(@"C:\Communicate.pfx", "xxxxxxxx");
X509Certificate2Collection col = new X509Certificate2Collection();
col.Add(cert);
TcpClient client = new TcpClient(args[0], int.Parse(args[1]));
Stream stream = client.GetStream();
SslStream ssl = new SslStream(stream, false, new RemoteCertificateValidationCallback((a, b, c, d) => { return true; }), new LocalCertificateSelectionCallback((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers)=> { return cert; }));
ssl.AuthenticateAsClient("1.1.1.1", col, System.Security.Authentication.SslProtocols.Tls12, false);
string x = "GET /api/TimebasedProxy/ HTTP/1.1\r\n";
x += "Host:1.1.1.1\r\n";
x += "Content-Type: application/json\r\n";
x += "Connection: Close\r\n\r\n";
byte[] xs = Encoding.UTF8.GetBytes(x);
ssl.Write(xs, 0, xs.Length);

Root Cause Found

After deeper investigation, I traced the issue to a server-side registry setting:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\SendTrustedIssuerList was set to 1.

On Windows Server 2012 R2, this setting forces Schannel to send a list of trusted issuers during the TLS handshake. HttpClient/WebRequest relies on Schannel's default certificate selection logic, which fails when the client certificate's issuer isn't included in that sent list. In contrast, curl/openssl and the custom SslStream code explicitly specify the client certificate, bypassing this selection logic entirely.

The Unexpected Culprit: IISCrypto Bug

We eventually found that this registry setting was being forced by IISCrypto. No matter what configuration changes we made in the tool—even unrelated ones—it would automatically set SendTrustedIssuerList to 1. This is confirmed to be a bug in IISCrypto.


内容的提问来源于stack exchange,提问作者Zonas Sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:12:32