С# и dotnet 4.7.1 не добавление специального сертификата для вызовов TLS 1.2

У меня есть следующий код С#, создающий вызов https с помощью специального сертификата. При использовании Tls 1.1 вызов работает нормально. При использовании Tls 1.2 вызов прерывается. Я использую curl, используя tls 1.2, отлично работает.

Код С#:

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;

Работает с:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

Ошибка с:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

. Сообщение об ошибке: 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, который будет использоваться, что среди поддерживаемых шифров.

В wirehark я вижу, что с рабочими вызовами (С#/Tls 1.1 и Curl Tls 1.2) сертификат отправляется на сервер. Вот дамп проводов для вызова С# tls 1.1:

Дамп Wireshark - Csharp tls 1.1

Однако, также в wirehark, я вижу, что с С#/Tls 1.2 от клиента к серверу не отправляется сертификат. Вот дамп проводов для вызова С# tls 1.2:

введите описание изображения здесь

Может ли кто-нибудь увидеть, чего я здесь не вижу?

UPDATE

Кажется, что у сертификата есть подпись md5, которая не поддерживается Schannel в окнах в сочетании с tls 1.2. Наш поставщик создал для нас еще один сертификат как решение.

Я столкнулся с этой случайной нитью, которая обсуждает проблему: https://community.qualys.com/thread/15498

Ответы

Ответ 1

Я считаю, что этот код маскирует некоторый тип ошибки сертификата, всегда слепо возвращая true:

handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true;

Я рекомендую вам иметь функцию, чтобы действительно анализировать результаты arg4. Это ваши ошибки политики SSL. Запишите их, и вы получите ответ. В моем примере я пишу на консоль, но вы можете писать в трассировку или файл. Вы получите номер, которому будет присвоено значение для перечисления SslPolicyErrors. На основе результатов вам может потребоваться проверить ваш arg3, который является вашей цепочкой.

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => {

SslPolicyErrors errs = sslPolicyErrors;
Console.WriteLine("Policy Errors " + sslPolicyErrors.ToString());           
return true;};

Ответ 2

Не следует ли указать свойство handler SslProtocols?

Попробуйте добавить эту строку после определения hander:

handler.SslProtocols = SslProtocols.Tls12;