Domyślny protokół zabezpieczeń w .NET 4.5


253

Jaki jest domyślny protokół bezpieczeństwa do komunikacji z serwerami, które obsługują do TLS 1.2? Będzie .NETdomyślnie wybierać najwyższej protokół zabezpieczeń obsługiwane po stronie serwera, czy muszę jawnie dodać poniższy wiersz kodu:

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

Czy istnieje sposób na zmianę tego ustawienia domyślnego oprócz zmiany kodu?

Wreszcie, obsługuje .NET 4.0tylko do TLS 1.0? tj. muszę zaktualizować projekty klienta do 4.5, aby je obsługiwać TLS 1.2.

Moją motywacją jest usunięcie obsługi SSLv3po stronie klienta, nawet jeśli serwer ją obsługuje (mam już skrypt PowerShell, aby wyłączyć to w rejestrze komputera) i obsługę najwyższego protokołu TLS obsługiwanego przez serwer.

Aktualizacja: Patrząc na ServicePointManagerklasę .NET 4.0nie widzę wyliczonych wartości dla TLS 1.0i 1.1. W obu .NET 4.0/4.5przypadkach wartością domyślną jest SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Mamy nadzieję, że to ustawienie domyślne nie ulegnie awarii przez wyłączenie SSLv3w rejestrze.

Zdecydowałem jednak, że muszę zaktualizować wszystkie aplikacje .NET 4.5i i tak jawnie dodać je SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;do kodu ładowania wszystkich aplikacji.

Spowoduje to wysłanie żądań wychodzących do różnych aplikacji i usług, aby nie obniżać poziomu SSLv3i należy wybrać najwyższy poziom TLS.

Czy to podejście wydaje się rozsądne czy nadmierne? Mam wiele aplikacji do zaktualizowania i chcę je w przyszłości sprawdzić, ponieważ słyszę, że TLS 1.0niektórzy dostawcy mogą nawet w najbliższej przyszłości stracić ważność.

Czy jako klient wysyłający żądania wychodzące do interfejsów API wyłączenie protokołu SSL3 w rejestrze ma nawet wpływ na środowisko .NET? Domyślnie TLS 1.1 i 1.2 nie są włączone, czy musimy włączyć to przez rejestr? RE http://support.microsoft.com/kb/245030 .

Po krótkiej analizie uważam, że ustawienia rejestru nie będą miały wpływu, ponieważ dotyczą IIS (podklucz serwera) i przeglądarek (podklucz klienta).

Przepraszamy, ten post zamienił się w wiele pytań, a następnie w odpowiedzi „być może”.


FYI: Najnowsze najlepsze praktyki dotyczące TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/…
JohnLBevan

Dla tych, którzy chcą zobaczyć najlepszą odpowiedź na to pytanie, posortuj według głosów!
navule

1
Powiązane SO Pytania i odpowiedzi: stackoverflow.com/questions/41618766/... Czytelnicy powinni zauważyć, że to pytanie się starzeje, a nowe zalecenia obowiązują od 2020 r.
Brak zwrotów Brak zwrotów

Odpowiedzi:


280

Niektórzy pozostawiający komentarze zauważyli, że ustawienie System.Net.ServicePointManager.SecurityProtocolokreślonych wartości oznacza, że ​​aplikacja nie będzie mogła korzystać z przyszłych wersji TLS, które mogą stać się wartościami domyślnymi w przyszłych aktualizacjach platformy .NET. Zamiast określać stałą listę protokołów, możesz zamiast tego włączać lub wyłączać protokoły, które znasz i na których Ci zależy, pozostawiając inne takie, jakie są.

Aby włączyć TLS 1.1 i 1.2 bez wpływu na inne protokoły:

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

Zauważ, że |=możesz włączyć te flagi bez wyłączania innych.

Aby wyłączyć SSL3 bez wpływu na inne protokoły:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;

6
To jest naprawdę poprawna odpowiedź. Zaakceptowana odpowiedź zapewni, że Twoja aplikacja będzie zawsze wyłączać nowe wersje TLS, chyba że wrócisz i zaktualizujesz kod.
Connor,

5
@Gertsen Nie, to trochę bitowe, więc włącza odpowiednie bity, jeśli są wyłączone. Jeśli te bity są już włączone, zmiana nie nastąpi.
Scott

3
A odpowiednikiem tego PowerShell jest [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod opiera się na tych samych bazowych bibliotekach .NET.
Martin Hollingsworth,

15
Ponieważ nikt nie mówi o tym, gdzie umieścić ten kod, z powodzeniem umieściłem go w Application_Start Global.asax.cs dla mojej aplikacji ASP.NET MVC. Szukałem sposobu, w jaki moje żądania SMTP mają być wysyłane przez TLS1.2, a NIE przez TLS1.0. Dodałem również & = ~ SecurityProtocolType.Tls, aby wyłączyć TLS 1.0
Greg Veres

2
W VB odpowiednikiem jestNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codespaced

188

Domyślnie System.Net.ServicePointManager.SecurityProtocolw obu .NET 4.0/4.5jest SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0obsługuje do TLS 1.0chwili .NET 4.5obsługuje doTLS 1.2

Jednak kierowanie na aplikacje .NET 4.0może nadal obsługiwać, nawet TLS 1.2jeśli .NET 4.5jest zainstalowane w tym samym środowisku. .NET 4.5instaluje się na górze .NET 4.0, zastępując System.dll.

Zweryfikowałem to, obserwując poprawny protokół bezpieczeństwa ustawiony w ruchu fiddler4zi ręcznie ustawiając wyliczone wartości w .NET 4.0projekcie:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 |
(SecurityProtocolType)768 | (SecurityProtocolType)3072;

Odniesienie:

namespace System.Net
{
    [System.Flags]
    public enum SecurityProtocolType
    {
       Ssl3 = 48,
       Tls = 192,
       Tls11 = 768,
       Tls12 = 3072,
    }
}

Jeśli spróbujesz włamać się do środowiska z .NET 4.0zainstalowanym TYLKO , otrzymasz wyjątek:

Nieobsługiwany wyjątek: System.NotSupportedException: Żądany protokół zabezpieczeń nie jest obsługiwany. w System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

Jednak nie poleciłbym tego „hacka”, ponieważ przyszła łatka itp. Może go złamać. *

Dlatego zdecydowałem, że najlepszą drogą do usunięcia wsparcia SSLv3jest:

  1. Uaktualnij wszystkie aplikacje do .NET 4.5
  2. Dodaj następujący kod do kodu boostrapping, aby zastąpić domyślny i przyszły dowód:

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

* Ktoś mnie poprawi, jeśli ten hack jest nieprawidłowy, ale wstępne testy widzę, że działa


6
Proszę zobaczyć imperialviolet.org/2014/12/08/poodleagain.html „Wydaje się, że to dobry moment, aby powtórzyć, że wszystko mniej niż TLS 1.2 z pakietem szyfrów AEAD jest kryptograficznie uszkodzone”.
Neil,

3
@Mathew, wyświetlając kod źródłowy ServicePointManager.cszobaczyć referencesource.microsoft.com/#System/net/System/Net/...
Luke Hutton

12
Ciągle widzę, że ludzie twierdzą, że .NET 4.5domyślne są wartości Tls12 - ale jak już tu napisałeś, tak nie jest. Daje ci możliwość użycia go doSecurityProtocol
Don Cheadle

17
Nie będę głosować za tą odpowiedzią, ponieważ zawiera ona wiele przydatnych informacji, ale implementacja wersji protokołu zakodowanego na stałe nie jest dobrym pomysłem, ponieważ ograniczy stosowanie najlepszej dostępnej metody szyfrowania i może spowodować problemy z bezpieczeństwem. Zmiany rejestru mające na celu zmianę domyślnego zachowania .Net w celu obsługi nowoczesnych protokołów są o wiele bardziej zalecane. (Warto jednak zauważyć, że zmiana rejestru wyłącza także SSL v3.)
AJ Henderson

6
W wersji FW 4.6 i 4.7 wartość domyślna jest zgodna z support.microsoft.com/en-us/help/3069494SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 /...
Ian Kemp

68

Możesz zastąpić domyślne zachowanie w następującym rejestrze:

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

i

Key  : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1

Aby uzyskać szczegółowe informacje, zobacz wdrożenieServicePointManager .


Dzięki, nie wiedziałem o tym. Przetestuję to. Stworzyłem skrypt Powershella, aby go ustawić: gist.github.com/lukehutton/ab80d207172a923401b1
Luke Hutton

6
Zmiana rejestru nie wygląda na dobre rozwiązanie. Jeśli aplikacja chce obsługiwać TLS1, powinna się o nią przekonać. Nie działające środowisko. W przeciwnym razie może zaszkodzić innym aplikacjom lub zrobić piekło z wdrażania i aktualizacji aplikacji.
Michaił G

13
@MikhailG wręcz przeciwnie. Zmiana rejestru jest preferowaną metodą. SChannel zapewnia abstrakcję podstawowych negocjacji i chcesz, aby Twoja aplikacja używała najwyższego obsługiwanego poziomu bezpieczeństwa. Sztuczne ograniczenie go w oprogramowaniu powoduje przyszłe problemy, gdy zostaną wydane nowe protokoły, a twoje oprogramowanie nie będzie mogło ich używać. Byłoby miło, gdyby istniała opcja powiedzenia, że ​​w oprogramowaniu używa się tylko lepszego protokołu niż określony, ale nie ma takiej opcji bez uniemożliwienia działania przyszłych wersji. Wyłączono SSL v3 z tą zmianą ..
AJ Henderson

13
Wiersz polecenia: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(i / lub /reg:32)
Kevin Smyth

7
@MikhailG: Ustawienie rejestru nie uniemożliwia aplikacjom obsługi starszych protokołów. Zmienia tylko wartości domyślne (które obejmują teraz tls 1.0). Ponadto domyślnym zachowaniem w .Net 4.6+ jest użycie silnego szyfrowania; w takim przypadku ten wpis rejestru byłby użyteczny tylko jako sposób na wyłączenie silnego szyfrowania.
Brian

51

Utwórz plik tekstowy z .regrozszerzeniem i następującą zawartością:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

Lub pobierz go z następującego źródła:

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg

Kliknij dwukrotnie, aby zainstalować ...


3
Podany link wydaje się mieć problemy z certyfikatem SSL.
NathanAldenSr

Nawet po dodaniu tych kluczy rejestru nadal mam ten problem. Dowolny pomysł ?
Samidjo

@Samidjo - jakiej wersji .NET używasz? Odpowiedź Luke'a jest o wiele bardziej szczegółowa niż moja, ale wygląda na to, że musisz mieć przynajmniej .NET 4.5 zainstalowany. Ponadto, jeśli właśnie dokonałeś zmiany, może być konieczne ponowne przetworzenie puli aplikacji. To są domysły, więc bez bardziej szczegółowych informacji mogę być w stanie pomóc znacznie dalej :)
dana

2
Niedawno zastosowana łata support.microsoft.com/en-us/help/4019114/... na serwer spowodowała awarię naszej aplikacji .net 4.5.2 w przypadku żądań REST https. Te klucze rozwiązały nasz problem.
Kleinux

21

Przekonałem się, że kiedy podam tylko TLS 1.2, nadal będzie negocjować do 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Podałem to w metodzie uruchamiania Global.asax dla mojej aplikacji sieci web .net 4.5.


2
Jaki jest obsługiwany protokół bezpieczeństwa na serwerze? Uważam, że jest to również czynnik tutaj i może być 1.1 to najnowsza wersja na serwerze. www.passionatecoder.ca
Ehsan

14
Pozytywnie oceniany, ponieważ jest to jedyna odpowiedź, która mówi GDZIE umieścić wiersz kodu będący rozwiązaniem.
jgerman

1
Klient (np. Twój C # WebClient) i serwer (serwer API, do którego dzwonisz) będą negocjować użycie najwyższego protokołu, który oba obsługują. Więc jeśli twój klient obsługuje TLS 1.2, ale serwer tylko TLS 1.1 - Klient użyje TLS 1.1 (chyba że USUŃ TLS 1.1 od swojego klienta - w takim przypadku może nie znaleźć protokołu obsługiwanego wspólnie, a klient popełni błąd)
Don Cheadle

Musiałem dodać przy użyciu System.Net w global.asax.cs
Patrick

16

Poniższy kod będzie:

  • drukuj włączone protokoły
  • wydrukuj dostępne protokoły
  • włącz TLS1.2, jeśli platforma go obsługuje i jeśli nie jest włączony, na początek
  • wyłącz SSL3, jeśli jest włączony
  • wydrukuj wynik końcowy

Stałe:

  • 48 to SSL3
  • 192 to TLS1
  • 768 to TLS1.1
  • 3072 to TLS1.2

Nie wpłynie to na inne protokoły. To sprawia, że ​​jest to zgodne z przyszłymi protokołami (Tls 1.3 itp.).

Kod

// print initial status
    Console.WriteLine("Runtime: " + System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion);
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);
    Console.WriteLine("Available protocols: ");
    Boolean platformSupportsTls12 = false;
    foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) {                
        Console.WriteLine(protocol.GetHashCode());
        if (protocol.GetHashCode() == 3072){
            platformSupportsTls12 = true;
        }
    }
    Console.WriteLine("Is Tls12 enabled: " + ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072));    


// enable Tls12, if possible
    if (!ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072)){
        if (platformSupportsTls12){
            Console.WriteLine("Platform supports Tls12, but it is not enabled. Enabling it now.");
            ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072;
        } else {
            Console.WriteLine("Platform does not supports Tls12.");
        }
    }

// disable ssl3
   if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Ssl3)) { 
      Console.WriteLine("Ssl3SSL3 is enabled. Disabling it now.");
      // disable SSL3. Has no negative impact if SSL3 is already disabled. The enclosing "if" if just for illustration.
      System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;                      
   }
    Console.WriteLine("Enabled protocols:   " + ServicePointManager.SecurityProtocol);

Wynik

Runtime: 4.7.2114.0
Enabled protocols:   Ssl3, Tls
Available protocols: 
0
48
192
768
3072
Is Tls12 enabled: False
Platform supports Tls12, but it is not enabled. Enabling it now.
Ssl3 is enabled. Disabling it now.
Enabled protocols:   Tls, Tls12

14

Mam problem, gdy mój klient zaktualizował TLS z 1.0 do 1.2. Moja aplikacja korzysta z .NET Framework 3.5 i działa na serwerze. Naprawiłem to w ten sposób:

  1. Napraw program

Przed wywołaniem HttpWebRequest.GetResponse () dodaj następujące polecenie:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

Rozszerza 2 biblioteki DLL, dodając 2 nowe klasy: System.Net i System.Security.Authentication

    namespace System.Net
    {
        using System.Security.Authentication;
        public static class SecurityProtocolTypeExtensions
        {
            public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
            public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11;
            public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0;
        }
    } 

    namespace System.Security.Authentication
    {
        public static class SslProtocolsExtensions
        {
            public const SslProtocols Tls12 = (SslProtocols)0x00000C00;
            public const SslProtocols Tls11 = (SslProtocols)0x00000300;
        }
    } 
  1. Zaktualizuj pakiet Microsoft

Pobierz pakiet:

  • W systemie Windows 2008 R2: Windows6.1-kb3154518-x64.msu
  • W systemie Windows 2012 R2: Windows8.1-kb3154520-x64.msu

Aby pobrać partię i więcej szczegółów, możesz zobaczyć tutaj:

https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-.net-framework-3.5.1-on-windows-7 -sp1-and-server-2008-r2-sp1


1
czy jest możliwa zmiana SecurityProtocol bez zmiany kodu źródłowego? jak machine.config lub app.config.
ahankendi

1
Łał. To nagroda voodoo roku… rzeczy… właśnie tam. Kołyszesz przedmieścia!
granadaCoder

14

Mechanizm zmiany rejestru zadziałał dla mnie po walce. Właściwie moja aplikacja działała w wersji 32-bitowej. Musiałem więc zmienić wartość pod ścieżką.

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319

Typem wartości musi być DWORD, a wartość powyżej 0. Lepsze użycie 1.Ustawienia rejestru, aby uzyskać aplikację .Net 4.0, należy użyć TLS 1.2, pod warunkiem że.


To nie jest dokładne. W przypadku .NET 4.5.2 należy ustawić wartość 1 (lub wyższą); ale w przypadku .NET 4.6 wystarczy ustawić wartość 0 (tzn. można ją rozbroić).
Jirka Hanika,

Och, nie testowałem w .Net 4.6. Moje ustalenia znajdują się w blogu joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru,

Wspomniany klucz rejestru powinien brzmieć „Wow6432Node”. Z jakiegoś powodu pominąłeś część „Węzeł”. Próbowałem edytować twoją odpowiedź, ale moja zmiana składała się tylko z 4 liter, więc nie pozwoliła mi. : \
Jeffrey LeCours,

Musiałem odrzucić IIS, aby to ustawienie było aktywne jako domyślne.
Jeff Mitchell,

10

Korzystam z .NET 4.5.2 i nie byłem zadowolony z żadnej z tych odpowiedzi. Ponieważ rozmawiam z systemem obsługującym TLS 1.2 i widzę, że wszystkie SSL3, TLS 1.0 i TLS 1.1 są zepsute i niebezpieczne w użyciu, nie chcę włączać tych protokołów. W .NET 4.5.2 protokoły SSL3 i TLS 1.0 są domyślnie włączone, co widzę w kodzie poprzez sprawdzenieServicePointManager.SecurityProtocol . W .NET 4.7 jest nowySystemDefaulttryb protokołu, który wyraźnie przekazuje wybór protokołu systemowi operacyjnemu, w którym moim zdaniem poleganie na rejestrze lub innych ustawieniach konfiguracji systemu byłoby odpowiednie. Nie wydaje się to jednak obsługiwane w .NET 4.5.2. W interesie pisania kodu kompatybilnego z systemem, który będzie podejmował właściwe decyzje, nawet jeśli TLS 1.2 zostanie nieuchronnie zepsuty w przyszłości lub gdy uaktualnię do .NET 4.7+ i przekażę większą odpowiedzialność za wybór odpowiedniego protokołu do systemu operacyjnego , Przyjąłem następujący kod:

SecurityProtocolType securityProtocols = ServicePointManager.SecurityProtocol;
if (securityProtocols.HasFlag(SecurityProtocolType.Ssl3) || securityProtocols.HasFlag(SecurityProtocolType.Tls) || securityProtocols.HasFlag(SecurityProtocolType.Tls11))
{
    securityProtocols &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11);
    if (securityProtocols == 0)
    {
        securityProtocols |= SecurityProtocolType.Tls12;
    }
    ServicePointManager.SecurityProtocol = securityProtocols;
}

Ten kod wykryje, gdy włączony zostanie znany niezabezpieczony protokół, iw takim przypadku usuniemy te niebezpieczne protokoły. Jeśli nie pozostaną żadne inne jawne protokoły, wymusimy włączenie TLS 1.2, jako jedynego znanego bezpiecznego protokołu obsługiwanego przez .NET w tym momencie. Ten kod jest zgodny z poprzednimi wersjami, ponieważ weźmie pod uwagę nowe typy protokołów, o których nie wie, że zostaną dodane w przyszłości, a także będzie dobrze grał z nowymSystemDefaultstan w .NET 4.7, co oznacza, że ​​nie będę musiał ponownie odwiedzać tego kodu w przyszłości. Zdecydowanie zalecam przyjęcie takiego podejścia, zamiast bezwarunkowego kodowania jakichkolwiek stanów protokołu bezpieczeństwa bezwarunkowo, w przeciwnym razie będziesz musiał ponownie skompilować i zastąpić klienta nową wersją w celu uaktualnienia do nowego protokołu bezpieczeństwa, gdy TLS 1.2 jest nieuchronnie zepsuty, lub bardziej prawdopodobne, że będziesz musiał pozostawić istniejące niepewne protokoły włączone na lata na serwerze, co czyni Twoją organizację celem ataków.


1
Ta odpowiedź wydaje się jednak najbardziej przemyślana, chyba że czegoś mi brakuje, nie jestem pewien, czy będzie kompatybilna z przodu, gdy TLS 1.2 nieuchronnie się zepsuje. Z tego, co widzę w mojej aplikacji .NET 4.7.2, SecurityProtocolType.SystemDefaultflaga jest oceniana na 0, więc sprawdzanie if (securityProtocols == 0)za pomocą włącznika bitowego lub flagi dla TLS 1.2 zawsze będzie zawierało TLS 1.2, nawet po „zerwaniu”, prawda? Nie ostre strzelanie tutaj. Naprawdę staram się znaleźć najlepszą drogę do przodu.
Griswald_911,

Mam zmodyfikowany kod na umieszczenie i wydaje się działać i być zgodny przodu: if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911

@ Griswald_911, mam podobny kod w mojej aplikacji konsolowej w wersji 4.7.2 i znalazłem ten wiersz securityProtocols |= SecurityProtocolType.Tls12;(bez bloku jeśli) nie zachowuje SystemDefault, securityProtocols ma tylko TLS2 później. Czy masz na myśli, gdy wartość ma wartość SystemDefault, żadna wartość nie powinna być aktualizowana? Jeśli chodzi o kompatybilność do przodu, czy zakładasz, że system operacyjny zajmie się włączeniem nowszego protokołu, takiego jak TLS 1.3?
Yang

@Yang - poprawnie. Wiersz securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the wyliczenia SecurityProtocolType` ma [Flags]atrybut, a wartością wyliczenia SystemDefault jest 0, wartość SystemDefault zostanie usunięta, nawet jeśli została wcześniej ustawiona. W rezultacie możesz ustawić wartość SevicePointManager.SecurityProtocol 0 lub dowolną kombinację innych wartości wyliczenia. Jeśli ustawisz go na SystemDefault, zasadniczo rezygnujesz z samodzielnego określania protokołu i pozwalasz systemowi decydować.
Griswald_911

1
@Yang - Chodzi o to, że po ustawieniu wartości na SystemDefault aplikacja powinna używać tego, co określa system operacyjny - którym jest TLS 1.2 w najnowszych wersjach systemu Windows 10. Pomysł polega na tym, że w przyszłości, gdy TLS 1.3 stanie się standard nie powinien modyfikować aplikacji, aby dziedziczyć tę funkcjonalność. Zapoznaj się z dokumentacją tutaj , w której SystemDefault „pozwala systemowi operacyjnemu wybrać najlepszy używany protokół i zablokować protokoły, które nie są bezpieczne”.
Griswald_911

6

Firma Microsoft opublikowała ostatnio najlepsze praktyki dotyczące tego. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Podsumowanie

Celuj w .Net Framework 4.7, usuń dowolny kod ustawiający SecurityProtocol, dzięki czemu system operacyjny zapewni korzystanie z najbardziej bezpiecznego rozwiązania.

Uwaga: Należy również upewnić się, że najnowsza wersja TLS jest obsługiwana i włączona w systemie operacyjnym.

OS                          TLS 1.2 support

Windows 10                  \_ Supported, and enabled by default.
Windows Server 2016         /   
Windows 8.1                 \_ Supported, and enabled by default.
Windows Server 2012 R2      /
Windows 8.0                 \_ Supported, and enabled by default.
Windows Server 2012         /
Windows 7 SP1               \_ Supported, but not enabled by default*.
Windows Server 2008 R2 SP1  /
Windows Server 2008         -  Support for TLS 1.2 and TLS 1.1 requires an update. See Update to add support for TLS 1.1 and TLS 1.2 in Windows Server 2008 SP2.
Windows Vista               -  Not supported.

* To enable TLS1.2 via the registry see https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

Aby uzyskać więcej informacji i starszych struktur, zapoznaj się z linkiem MS.


3
Problem polega na tym, że tls 1.1 i tls 1.2 nie będą działać w systemach Windows 7 i Server 2008, jeśli będziesz postępować zgodnie z wytycznymi (utrzymanie SecurityProtocolType.SystemDefault), ponieważ nie są one „włączone” (cokolwiek to znaczy) w tych systemach operacyjnych bez zmiany rejestru. To sprawia, że ​​SystemDefault jest w praktyce zepsuty przez projekt. Microsoft naprawdę to zepsuł.
osexpert

Niezły, dzięki @osexpert, dobry połów. Poprawiłem odpowiedź, aby zawierała informacje o obsługiwanych systemach operacyjnych, więc nie ma niespodzianek dla osób korzystających ze starszych systemów operacyjnych, w których samo kierowanie na 4.7 nie wystarczy.
JohnLBevan,

1
Uwaga: istnieje również KB, aby włączyć nowsze protokoły w niektórych systemach operacyjnych: support.microsoft.com/en-my/help/3140245/…
JohnLBevan

1
Jeśli ustawienia rejestru nie są opcją, myślę, że to najlepsze rozwiązanie dla .NET 4.7+: if (System.Environment.OSVersion.Version < new Version(6, 2) /* Windows 8 */) ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; else ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
osexpert

5

Dla kompletności, oto skrypt Powershell, który ustawia wyżej wymienione klucze rejestru:

new-itemproperty -path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord";
new-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord"

2

Alternatywa dla twardego kodu ServicePointManager.SecurityProtocollub jawnego klucza SchUseStrongCrypto , jak wspomniano powyżej:
Możesz .NET może używać domyślnych ustawień SCHANNEL z kluczem SystemDefaultTlsVersions,
np .:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001

2

Najlepszym rozwiązaniem tego problemu wydaje się być uaktualnienie do wersji .NET 4.6 lub nowszej, która automatycznie wybierze silne protokoły, a także silne szyfry.

Jeśli nie możesz zaktualizować do wersji .NET 4.6, porada dotycząca ustawienia

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

I używając ustawień rejestru:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD z 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD z 1

Skutkuje użyciem czegoś innego niż TLS 1.0 i silnego szyfru.

W moich testach tylko ustawienie w Wow6432Node robiło różnicę, mimo że moja aplikacja testowa została zbudowana dla dowolnego procesora.


Wyjaśnienie: wystarczy ustawić SevicePointManager.SecurityProtocol LUB ustawić ustawienia rejestru. Nie trzeba robić obu. W mojej aplikacji zdecydowałem się po prostu ustawić ServicePointManager.SecurityProtocol. Moje rozumowanie jest takie, że ustawienie rejestru wpływa na całą maszynę i nie chciałem, aby ktoś złamał aplikację, ponieważ zależało to od TLS 1.0.
GWC,

1

Zgodnie z najlepszymi praktykami Transport Layer Security (TLS) z .NET Framework : Aby zapewnić bezpieczeństwo aplikacji .NET Framework, wersja TLS nie powinna być zakodowana na stałe. Zamiast tego ustaw klucze rejestru: SystemDefaultTlsVersions i SchUseStrongCrypto :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

0

Jeśli możesz korzystać z .NET 4.7.1 lub nowszej wersji, użyje TLS 1.2 jako minimalnego protokołu opartego na możliwościach systemu operacyjnego. Zgodnie z zaleceniami Microsoft:

To ensure .NET Framework applications remain secure, the TLS version should not be hardcoded. .NET Framework applications should use the TLS version the operating system (OS) supports.

-2

Dla klucza: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Wartość: SchUseStrongCrypto

Musisz ustawić wartość na 1.


5
Myślę, że dostajesz negatywne zdanie, ponieważ to ta sama odpowiedź @Jira Mares, ale z mniej szczegółami
Stuart Siegler
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.