Uwierzytelnianie nie powiodło się, ponieważ strona zdalna zamknęła strumień transportu

87

Rozwijam klienta TCP do połączenia serwera OpenSSL z uwierzytelnianiem za pomocą certyfikatu. Używam plików .crt i .key udostępnionych przez zespół serwera. Te certyfikaty są generowane przez polecenia OpenSSL.

Używam SslStreamobiekt do uwierzytelnienia klienta TCP poprzez wywołanie SslStream.AuthenticateAsClientmetody przekazując serwer IP, SslProtocols.Ssl3i X509CertificateCollection.

Otrzymuję następujący błąd:

Uwierzytelnianie nie powiodło się, ponieważ strona zdalna zamknęła strumień transportu

Odelu
źródło
2
To wygląda na problem w dni po PUDEL: SslProtocols.Ssl3. Może powinieneś spróbować SslProtocols.Tls. W .Net 4.5 i nowszych możesz również użyć Tls11lub Tls12. Zobacz wyliczanie SslProtocols . Możesz mieć inne problemy.
jww
Dzięki. Mój problem został rozwiązany przez dołączenie certyfikatu z fizycznej ścieżki certyfikatu i hasła zamiast wyszukiwania nazwy podmiotu certyfikatu w magazynie certyfikatów systemu Windows.
Odelu
Teraz jestem w stanie uzyskać wynik ze wszystkich SslProtocols (SSL3, Tls1 i Tls2). Dzięki za odpowiedź
Odelu
@Odelu, jak rozwiązałeś problem? Po stronie klienta czy po stronie serwera?

Odpowiedzi:

155

Odradzałbym ograniczanie SecurityProtocol do TLS 1.1.

Zalecanym rozwiązaniem jest użycie

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

Inną opcją jest dodanie następującego klucza rejestru:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

Warto zauważyć, że .NET 4.6 będzie domyślnie używać poprawnego protokołu i nie wymaga żadnego rozwiązania.

GuiSim
źródło
6
wow, właśnie rozwiązałeś mój problem - próbowałem różnych rzeczy - a potem znalazłem się tutaj, widząc notatkę o frameworku. Po prostu przełączyłem go na 4.6.1 (używałem 4.5), mając nadzieję, że problem będzie polegał na tym, że framework może używać niewłaściwego protokołu bezpieczeństwa - i bingo, moje połączenia nie są odrzucane i otrzymuję moje dane!
Veverke
7
Ważne jest, aby powiedzieć, że System.Net.ServicePointManager.SecurityProtocol = ...należy to wykonać przed utworzeniem żądania.
Tonatio
2
ta docelowa aktualizacja frameworka do 4.6.1 uratowała mi życie :-)
Awais,
Mój framework jest ustawiony na 4.6.2. Może zamiast tego będę musiał użyć rozwiązania TLS
Luminous
Używam 4.7.2 Framework, również witryna, do której wysyłam żądanie, korzysta z TLS 1.2, ale tak jak w przypadku 6 żądań z 10 otrzymuję ten błąd. jakieś pomysły ?
Davit Mikuchadze
16

Jeśli chcesz użyć starszej wersji .net, utwórz własną flagę i rzuć ją.

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    public Session()
    {
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    }
Iguanaware
źródło
1
Nie musisz używać własnej klasy, możesz bezpośrednio rzutować liczby całkowite na SecurityProtocolTypeServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;
Yan F.
13

Dodanie poniższego kodu pomogło mi rozwiązać problem.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
mruczenie
źródło
8
using (var client = new HttpClient(handler))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            }

To zadziałało dla mnie

Sanket Sonavane
źródło
1
Bit krytyczny to następujący wiersz: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; Ta odpowiedź jest jednak świetna, ponieważ pokazuje, gdzie ta linia powinna pasować w typowym przypadku użycia.
Nick Painter
5

Napotkałem ten sam komunikat o błędzie podczas używania ChargifyNET.dll do komunikacji z interfejsem API ładowania. Dodanie chargify.ProtocolType = SecurityProtocolType.Tls12;do konfiguracji rozwiązało problem za mnie.

Oto pełny fragment kodu:

public ChargifyConnect GetChargifyConnect()
{
    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;
}
Tod Birdsall
źródło
2

W przypadku VB.NET możesz umieścić następujące informacje przed żądaniem sieci Web:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

To rozwiązało mój problem z bezpieczeństwem w .NET 3.5.

user1477388
źródło
0

Zdarzyło mi się to, gdy punkt końcowy żądania internetowego został przełączony na inny serwer, który akceptował tylko żądania TLS1.2. Wypróbowałem tak wiele prób, które można znaleźć głównie w Stackoverflow, takich jak

  1. Klucze rejestru,
  2. Dodano:
    System.Net.ServicePointManager.SecurityProtocol | = System.Net.SecurityProtocolType.Tls12; do Global.ASX OnStart,
  3. Dodano w Web.config.
  4. Zaktualizowany .Net framework do 4.7.2 Nadal otrzymuję ten sam wyjątek.

Otrzymany wyjątek nie oddał rzeczywistego problemu, z którym miałem do czynienia, i nie znalazłem żadnej pomocy od operatora usługi.

Aby rozwiązać ten problem, muszę dodać nowy pakiet szyfrowania TLS_DHE_RSA_WITH_AES_256_GCM_SHA384. Użyłem narzędzia IIS Crypto 2.0 stąd, jak pokazano poniżej.

wprowadź opis obrazu tutaj

FunMatters
źródło