C#和dotnet 4.7.1没有为TLS 1.2调用添加自定义证书

Ste*_*yer 19 c# x509certificate2 tls1.2

我有以下C#代码,使用自定义证书构建https调用.使用Tls 1.1时,通话正常.使用Tls 1.2时,呼叫会中断.我使用curl,使用tls 1.2也可以正常工作.

C#代码:

X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import("C:\\SomePath\\MyCertificate.pfx", "MyPassword", X509KeyStorageFlags.PersistKeySet);
var cert = collection[0];

ServicePointManager.SecurityProtocol = ...;

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => true;
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true;
handler.ClientCertificates.Add(cert);

var content = new ByteArrayContent(Encoding.GetEncoding("latin1").GetBytes("Hello world"));
HttpClient client = new HttpClient(handler);
var resp = client.PostAsync(requestUri: url, content: content).Result.Content.ReadAsStringAsync().Result;
Run Code Online (Sandbox Code Playgroud)

适用于:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
Run Code Online (Sandbox Code Playgroud)

错误:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Run Code Online (Sandbox Code Playgroud)

.Net错误消息:SocketException:远程主机强制关闭现有连接

.Net版本:4.7.1

操作系统:Windows 10版本1703(支持的密码列表:https://msdn.microsoft.com/en-us/library/windows/desktop/mt808163(v = vs.85).aspx) - 服务器指定TLS_RSA_WITH_AES_256_GCM_SHA384为used,是支持的密码之一.

在wireshark中,我可以看到,通过工作调用(C#/ Tls 1.1和Curl Tls 1.2),证书将被发送到服务器.这是C#tls 1.1调用的wireshark转储:

Wireshark转储 -  Csharp转1.1

但是,在wireshark中,我可以看到,使用C#/ Tls 1.2,没有证书从客户端发送到服务器.这是C#tls 1.2调用的wireshark转储:

在此输入图像描述

谁能看到我在这里失踪的东西?

UPDATE

似乎证书有一个md5签名,Windows中的Schannel不支持tls 1.2.我们的供应商为我们创建了另一个证书作为解决方案.

我遇到了这个讨论问题的随机线程:https://community.qualys.com/thread/15498

小智 2

您对这个问题的根本原因是正确的:默认情况下,基于 schannel 的客户端提供 SHA1、SHA256、SHA384 和 SHA512(在 Win10/Server 2016 上)。因此 TLS 1.2 服务器不应将其 MD5 证书发送给这些客户端。

客户端(HttpClient)未在signature_algorithms扩展中列出MD5,因此TLS 1.2握手失败。修复方法是使用安全服务器证书。