Mam następujący kod C#, konstruując wywołanie https z certyfikatem niestandardowym. Podczas korzystania z Tls 1.1, połączenie działa poprawnie. Podczas korzystania z Tls 1.2 połączenie jest przerywane. Używam curl, używając TLC 1.2 również działa dobrze.C# i dotnet 4.7.1 nie dodawanie niestandardowego certyfikatu dla wywołań TLS 1.2
C# Kod:
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;
Działa z:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
Błąd:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
komunikat .Net: SocketException: Istniejące połączenie zostało gwałtownie zamknięte przez zdalny host
wersja .Net: 4.7.1
OS: Windows 10 w wersji 1703 (obsługiwane lista szyfr: https://msdn.microsoft.com/en-us/library/windows/desktop/mt808163(v=vs.85).aspx) - i serwer określa TLS_RSA_WITH_AES_256_GCM_SHA384 być używany, który jest jednym z obsługiwanych szyfrów.
W wireshark widzę, że przy połączeniach roboczych (C#/Tls 1.1 i Curl Tls 1.2) certyfikat jest wysyłany na serwer. Oto zrzut Wireshark dla C# tls 1.1 rozmowy:
Jednak również w Wireshark, widzę, że z C#/TLS 1.2 nie ma certyfikat wysyłane od klienta do serwera. Oto zrzut Wireshark dla C# tls 1.2 rozmowy:
Czy ktoś może zobaczyć, co ja tu brakuje?
UPDATE
Wydaje się, że certyfikat ma podpisu md5, który nie jest obsługiwany przez Schannel w oknach w połączeniu z TLS 1.2. Nasz dostawca utworzył dla nas kolejny certyfikat jako rozwiązanie.
natknąłem tej losowej wątku, który omawia problem: https://community.qualys.com/thread/15498
Miałem podobny problem z aplikacją klient/serwer .Net Core 2.0. Rozwiązałem, wymuszając na serwerze TLS 1.2. W ten sposób klient właściwie negocjuje protokół i certyfikat. Możesz spróbować połączyć się z serwerem, który jest zmuszony tylko do TLS 1.2 i zobaczyć, czy masz takie samo zachowanie w .NET Framework. – Ghigo
Dobrze to zmienić na serwerze, tak naprawdę nie jest tu opcja, ponieważ serwer należy do dostawcy. I nie ma znaczenia, czy dodaję tls 1.1 razem. Dopóki tls 1.2 jest tylko jednym z dozwolonych protokołów, ten problem ma miejsce. Muszę wiedzieć, dlaczego .net zachowuje się w ten sposób, gdy curl działa dobrze. I potrzebuję włączonej funkcji tls 1.2, ponieważ jest to ustawienie statyczne, a inne połączenia zależą od tls 1.2 w tej samej aplikacji. Gdybym mógł zmienić tls 1.3 dla tego pojedynczego połączenia, zrobiłby to. Ale ustawienie protokołów na obiekcie obsługi powoduje zgłoszenie wyjątku informującego, że nie jest to możliwe w bieżącym env. –
Wygląda trochę jak duplikat tego pytania https://stackoverflow.com/questions/44751179/tls-1-2-not-negotiated-in-net-4-7- bez -explicit-servicepointmanager-security –