Standard SecurityProtocol in .NET 4.5

253

Was ist das Standardsicherheitsprotokoll für die Kommunikation mit Servern, die bis zu unterstützen TLS 1.2? Wille.NET standardmäßig das höchste Sicherheitsprotokoll, das auf der Serverseite unterstützt wird, oder muss ich diese Codezeile explizit hinzufügen:

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

Gibt es neben einer Codeänderung eine Möglichkeit, diese Standardeinstellung zu ändern?

Schließlich unterstützt .NET 4.0nur bis zu TLS 1.0? dh ich muss Client-Projekte auf 4.5 aktualisieren, um zu unterstützenTLS 1.2 .

Meine Motivation ist es, die Unterstützung für zu entfernen SSLv3 auf der Clientseite auch wenn der Server dies unterstützt (ich habe bereits ein Powershell-Skript, um dies in der Maschinenregistrierung zu deaktivieren) und das höchste vom Server unterstützte TLS-Protokoll zu unterstützen.

Update: Wenn ich mir die ServicePointManagerKlasse in .NET 4.0ansehe, sehe ich keine aufgezählten Werte für TLS 1.0und 1.1. In beiden .NET 4.0/4.5Fällen ist die Standardeinstellung SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Hoffentlich wird dieser Standard nicht durch Deaktivieren SSLv3in der Registrierung unterbrochen.

Ich habe jedoch beschlossen, alle Apps auf alle Bootstrapping-Codes aller Anwendungen zu aktualisieren .NET 4.5und sie SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;trotzdem explizit hinzuzufügen .

Dadurch werden ausgehende Anforderungen an verschiedene APIs und Dienste gesendet, um kein Downgrade durchzuführen, SSLv3und es sollte die höchste Ebene von ausgewählt werden TLS.

Klingt dieser Ansatz vernünftig oder übertrieben? Ich muss viele Anwendungen aktualisieren, und ich möchte sie zukunftssicher machen, da ich höre, TLS 1.0dass einige Anbieter in naher Zukunft möglicherweise sogar veraltet sind.

Hat das Deaktivieren von SSL3 in der Registrierung als Client, der ausgehende Anforderungen an APIs stellt, überhaupt Auswirkungen auf das .NET Framework? Ich sehe standardmäßig, TLS 1.1 und 1.2 sind nicht aktiviert. Müssen wir es über die Registrierung aktivieren? RE http://support.microsoft.com/kb/245030 .

Nach einigen Nachforschungen glaube ich, dass die Registrierungseinstellungen keine Auswirkungen haben werden, da sie für IIS (Server-Unterschlüssel) und Browser (Client-Unterschlüssel) gelten.

Entschuldigung, dieser Beitrag wurde zu mehreren Fragen, gefolgt von "vielleicht" Antworten.

Luke Hutton
quelle
Zu Ihrer
Information
Für diejenigen, die die beste Antwort darauf sehen möchten, sortieren Sie nach Stimmen!
Navule
1
Verwandte SO Q & A: stackoverflow.com/questions/41618766/… Leser sollten beachten, dass diese Frage altert und neuere Empfehlungen ab 2020
vorliegen

Antworten:

280

Einige derjenigen, die Kommentare hinterlassen, haben diese Einstellung zur Kenntnis genommen System.Net.ServicePointManager.SecurityProtocol bestimmter Werte dazu führt, dass Ihre App zukünftige TLS-Versionen nicht nutzen kann, die möglicherweise die Standardwerte in zukünftigen Updates für .NET werden. Anstatt eine feste Liste von Protokollen anzugeben, können Sie stattdessen Protokolle aktivieren oder deaktivieren, die Sie kennen und für die Sie sich interessieren, und alle anderen Protokolle so lassen, wie sie sind.

So aktivieren Sie TLS 1.1 und 1.2, ohne andere Protokolle zu beeinflussen:

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

Beachten Sie die Verwendung von |= , um diese Flags einzuschalten, ohne andere auszuschalten.

So deaktivieren Sie SSL3, ohne andere Protokolle zu beeinflussen:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
Scott
quelle
6
Dies ist die wirklich richtige Antwort. Die akzeptierte Antwort stellt sicher, dass Ihre App immer neue TLS-Versionen ausschaltet, es sei denn, Sie gehen zurück und aktualisieren Ihren Code.
Connor
5
@Gertsen Nein, es ist ein bitweises oder, also schaltet es nur die entsprechenden Bits ein, wenn sie ausgeschaltet sind. Wenn diese Bits bereits aktiviert sind, erfolgt keine Änderung.
Scott
3
Das PowerShell-Äquivalent dazu lautet [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod und basiert auf denselben zugrunde liegenden .NET Framework-Bibliotheken.
Martin Hollingsworth
15
Da niemand darüber spricht, wo dieser Code abgelegt werden soll, habe ich ihn erfolgreich in Application_Start von Global.asax.cs für meine ASP.NET MVC-Anwendung eingefügt. Ich suchte nach einer Möglichkeit, meine SMTP-Anforderungen über TLS1.2 und NICHT über TLS1.0 zu senden. Ich habe auch & = ~ SecurityProtocolType.Tls hinzugefügt, um TLS 1.0
Greg Veres
2
In VB ist das ÄquivalentNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codespaced
188

Der Standard System.Net.ServicePointManager.SecurityProtocolin beiden .NET 4.0/4.5istSecurityProtocolType.Tls|SecurityProtocolType.Ssl3 .

.NET 4.0unterstützt bis zu einer TLS 1.0Weile.NET 4.5 unterstützt bis zuTLS 1.2

Jedoch ist eine Anwendung Targeting .NET 4.0unterstützen kann noch bis zu , TLS 1.2wenn .NET 4.5in der gleichen Umgebung installiert. .NET 4.5wird oben installiert .NET 4.0und ersetztSystem.dll .

Ich habe dies überprüft, indem ich das korrekte Sicherheitsprotokoll beobachtet habe, das im Datenverkehr mit festgelegt wurde, fiddler4und indem ich die aufgezählten Werte in einem .NET 4.0Projekt manuell festgelegt habe :

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

Referenz:

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

Wenn Sie den Hack in einer Umgebung versuchen, in der NUR .NET 4.0installiert ist, wird die Ausnahme angezeigt:

Nicht behandelte Ausnahme: System.NotSupportedException: Das angeforderte Sicherheitsprotokoll wird nicht unterstützt. bei System.Net.ServicePointManager.set_SecurityProtocol (Wert von SecurityProtocolType)

Ich würde diesen "Hack" jedoch nicht empfehlen, da ein zukünftiger Patch usw. ihn möglicherweise beschädigen kann. *

Aus diesem Grund habe ich beschlossen, dass der beste Weg zum Entfernen der Unterstützung folgende SSLv3ist:

  1. Aktualisieren Sie alle Anwendungen auf .NET 4.5
  2. Fügen Sie dem Boostrapping-Code Folgendes hinzu, um den Standard- und Zukunftssicherungscode zu überschreiben:

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

* Jemand korrigiert mich, wenn dieser Hack falsch ist, aber erste Tests, die ich sehe, funktionieren

Luke Hutton
quelle
6
Siehe imperialviolet.org/2014/12/08/poodleagain.html "Dies scheint ein guter Moment zu sein, um zu wiederholen, dass alles, was weniger als TLS 1.2 mit einer AEAD-Verschlüsselungssuite ist, kryptografisch kaputt ist."
Neil
3
@Mathew, durch Anzeigen des Quellcodes von ServicePointManager.cssiehe Referenzenource.microsoft.com/#System/net/System/Net/…
Luke Hutton
12
Ich sehe immer wieder Leute, die .NET 4.5die Standardeinstellungen für Tls12 beanspruchen - aber wie Sie hier angegeben haben, ist dies nicht der Fall. Es gibt Ihnen die Möglichkeit, es fürSecurityProtocol
Don Cheadle
17
Ich werde diese Antwort nicht ablehnen, da sie viele hilfreiche Informationen enthält. Die Implementierung einer fest codierten Protokollversion ist jedoch keine gute Idee, da sie die Verwendung der besten verfügbaren Verschlüsselung für die Anwendung einschränkt und später zu Sicherheitsproblemen führen kann. Die Registrierung ändert sich, um das Standardverhalten von .Net so zu ändern, dass moderne Protokolle tatsächlich unterstützt werden. (Es ist jedoch erwähnenswert, dass die Registrierungsänderung auch SSL v3 deaktiviert.)
AJ Henderson
6
Auf FW 4.6 und 4.7 ist der Standard jetzt SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12unter support.microsoft.com/en-us/help/3069494/…
Ian Kemp
68

Sie können das Standardverhalten in der folgenden Registrierung überschreiben:

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

und

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

Einzelheiten finden Sie in der Implementierung vonServicePointManager .

Jiri Mares
quelle
Danke, das wusste ich nicht. Ich werde es testen. Ich habe ein Powershel-Skript erstellt, um es festzulegen
Luke Hutton
6
Das Ändern der Registrierung scheint keine gute Lösung zu sein. Wenn die Anwendung TLS1 unterstützen möchte, sollte die Anwendung dies berücksichtigen. Nicht die laufende Umgebung. Andernfalls könnte es anderen Anwendungen schaden oder die Bereitstellung und Aktualisierung Ihrer Anwendung erschweren.
Mikhail G
13
@MikhailG ganz im Gegenteil. Die Registrierungsänderung ist die bevorzugte Methode. SChannel bietet eine Abstraktion der zugrunde liegenden Aushandlung, und Sie möchten, dass Ihre Anwendung die höchste unterstützte Sicherheitsstufe verwendet. Eine künstliche Einschränkung der Software führt zu zukünftigen Problemen, wenn neue Protokolle veröffentlicht werden und Ihre Software diese nicht verwenden kann. Es wäre schön, wenn es eine Option gäbe, zu sagen, dass nur eine bessere Verwendung als ein bestimmtes Protokoll in der Software verwendet wird, aber es gibt keine Option dafür, ohne auch zu verhindern, dass zukünftige Versionen funktionieren. Das hat SSL v3 mit dieser Änderung allerdings deaktiviert.
AJ Henderson
13
Befehlszeile: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(und / oder /reg:32)
Kevin Smyth
7
@MikhailG: Das Festlegen der Registrierung verhindert nicht, dass Anwendungen ältere Protokolle unterstützen. Es werden nur die Standardeinstellungen geändert (einschließlich tls 1.0 ab sofort). Das Standardverhalten in .Net 4.6+ ist die Verwendung von starker Krypto. In diesem Fall wäre dieser Registrierungseintrag nur nützlich, um starke Krypto zu deaktivieren.
Brian
51

Erstellen Sie eine Textdatei mit einer .regErweiterung und den folgenden Inhalten:

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

Oder laden Sie es von folgender Quelle herunter:

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

Doppelklicken Sie zum Installieren ...

Dana
quelle
3
Der von Ihnen angegebene Link weist anscheinend Probleme mit SSL-Zertifikaten auf.
NathanAldenSr
Selbst wenn ich diesen Registrierungsschlüssel hinzufüge, habe ich immer noch dieses Problem. Irgendeine Idee ?
Samidjo
@Samidjo - Welche .NET-Version verwenden Sie? Lukes Antwort geht viel detaillierter als meine, aber es sieht so aus, als müsste mindestens .NET 4.5 installiert sein. Wenn Sie gerade die Änderung vorgenommen haben, müssen Sie möglicherweise den App-Pool recyceln. Dies sind Vermutungen, so dass ich ohne weitere Details möglicherweise viel weiterhelfen kann :)
Dana
2
Ein kürzlich auf einen Server angewendeter Patch support.microsoft.com/en-us/help/4019114/… hat dazu geführt, dass unsere .net 4.5.2-Anwendung bei https-REST-Anforderungen fehlgeschlagen ist. Diese Schlüssel haben unser Problem gelöst.
Kleinux
21

Ich habe festgestellt, dass, wenn ich nur TLS 1.2 spezifiziere, es immer noch auf 1.1 verhandelt. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Ich habe dies in der Global.asax-Startmethode für meine .net 4.5-Webanwendung angegeben.

Jim
quelle
2
Was ist das unterstützte Sicherheitsprotokoll auf dem Server? Ich glaube, das ist auch hier ein Faktor und möglicherweise ist 1.1 die neueste Version auf dem Server. www.passionatecoder.ca
Ehsan
14
Upvoted, weil dies die einzige Antwort ist, die angibt, WO die Codezeile eingefügt werden soll, die die Lösung darstellt.
Jgerman
1
Der Client (z. B. Ihr C # WebClient) und der Server (API-Server, den Sie anrufen) verhandeln, um das höchste Protokoll zu verwenden, das beide unterstützen. Wenn Ihr Client TLS 1.2 unterstützt, der Server jedoch nur TLS 1.1 - der Client verwendet TLS 1.1 (es sei denn, Sie ENTFERNEN TLS 1.1 von Ihrem Client - in diesem Fall finden sie möglicherweise kein gegenseitig unterstütztes Protokoll, und der Client führt einen Fehler aus)
Don Cheadle
Musste mit System.Net in global.asax.cs hinzufügen
Patrick
16

Der folgende Code wird:

  • druckfähige Protokolle
  • verfügbare Protokolle drucken
  • Aktivieren Sie TLS1.2, wenn die Plattform dies unterstützt und wenn es zunächst nicht aktiviert ist
  • Deaktivieren Sie SSL3, wenn es aktiviert ist
  • Endergebnis drucken

Konstanten:

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

Andere Protokolle sind nicht betroffen. Dies macht dies kompatibel mit zukünftigen Protokollen (Tls1.3 usw.).

Code

// 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);

Ausgabe

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
Gerasoras
quelle
14

Ich habe das Problem erhalten, als mein Kunde TLS von 1.0 auf 1.2 aktualisiert hat. Meine Anwendung verwendet .net Framework 3.5 und wird auf dem Server ausgeführt. Also habe ich es so behoben:

  1. Korrigieren Sie das Programm

Fügen Sie vor dem Aufruf von HttpWebRequest.GetResponse () den folgenden Befehl hinzu:

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

Erweitert 2 DLLs durch Hinzufügen von 2 neuen Klassen: System.Net und 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. Aktualisieren Sie den Microsoft-Stapel

Batch herunterladen:

  • Für Windows 2008 R2: windows6.1-kb3154518-x64.msu
  • Für Windows 2012 R2: windows8.1-kb3154520-x64.msu

Zum Download Batch und weitere Details finden Sie hier:

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

Hieu
quelle
1
Ist es möglich, das SecurityProtocol zu ändern, ohne den Quellcode zu ändern? wie eine machine.config oder app.config.
Ahankendi
1
Beeindruckend. Das ist Voodoo des Jahres Award ... Zeug ... genau dort. Du rockst die Vororte!
GranadaCoder
14

Der Mechanismus zur Änderung der Registrierung hat nach einem Kampf für mich funktioniert. Eigentlich lief meine Anwendung als 32bit. Also musste ich den Wert unter Pfad ändern.

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

Der Werttyp muss DWORD und ein Wert über 0 sein. Besser 1 verwenden.Registrierungseinstellungen zum Abrufen der .NET 4.0-App verwenden TLS 1.2, sofern .NET 4.5 auf dem Computer installiert ist.

Joy George Kunjikkuru
quelle
Es ist nicht genau. Für .NET 4.5.2 muss dies auf 1 (oder höher) gesetzt werden. Für .NET 4.6 reicht es jedoch aus, nicht auf 0 gesetzt zu werden (dh es kann nicht gesetzt werden).
Jirka Hanika
Oh, ich habe nicht in .Net 4.6 getestet. Meine Ergebnisse sind dort in Blogpost joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru
Der von Ihnen erwähnte Registrierungsschlüssel sollte "Wow6432Node" lauten. Sie haben aus irgendeinem Grund den Teil "Knoten" weggelassen. Ich habe versucht, Ihre Antwort zu bearbeiten, aber meine Änderung bestand nur aus 4 Buchstaben, sodass ich nicht zugelassen wurde. : \
Jeffrey LeCours
Ich musste IIS bouncen, damit diese Einstellung standardmäßig selbst aktiviert wurde.
Jeff Mitchell
10

Ich arbeite unter .NET 4.5.2 und war mit keiner dieser Antworten zufrieden. Da ich mit einem System spreche, das TLS 1.2 unterstützt und SSL3, TLS 1.0 und TLS 1.1 defekt und für die Verwendung unsicher sind, möchte ich diese Protokolle nicht aktivieren. Unter .NET 4.5.2 sind die Protokolle SSL3 und TLS 1.0 standardmäßig aktiviert, was ich durch Überprüfen im Code sehen kannServicePointManager.SecurityProtocol . Unter .NET 4.7 gibt es das NeueSystemDefaultProtokollmodus, der die Auswahl des Protokolls explizit an das Betriebssystem übergibt, wobei ich der Meinung bin, dass es angemessen wäre, sich auf die Registrierung oder andere Systemkonfigurationseinstellungen zu verlassen. Dies scheint jedoch unter .NET 4.5.2 nicht unterstützt zu werden. Im Interesse des Schreibens von vorwärtskompatiblem Code trifft dies auch dann die richtigen Entscheidungen, wenn TLS 1.2 in Zukunft unvermeidlich beschädigt wird oder wenn ich auf .NET 4.7+ aktualisiere und mehr Verantwortung für die Auswahl eines geeigneten Protokolls an das Betriebssystem übergebe Ich habe den folgenden Code übernommen:

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;
}

Dieser Code erkennt, wenn ein bekanntes unsicheres Protokoll aktiviert ist. In diesem Fall werden diese unsicheren Protokolle entfernt. Wenn keine anderen expliziten Protokolle übrig bleiben, erzwingen wir die Aktivierung von TLS 1.2, dem einzigen bekannten sicheren Protokoll, das zu diesem Zeitpunkt von .NET unterstützt wird. Dieser Code ist vorwärtskompatibel, da er neue Protokolltypen berücksichtigt, von denen er nicht weiß, dass sie in Zukunft hinzugefügt werden, und er wird auch mit dem neuen gut funktionierenSystemDefaultStatus in .NET 4.7, was bedeutet, dass ich diesen Code in Zukunft nicht mehr besuchen muss. Ich würde dringend empfehlen, einen solchen Ansatz zu wählen, anstatt bestimmte Sicherheitsprotokollzustände bedingungslos fest zu codieren. Andernfalls müssen Sie Ihren Client neu kompilieren und durch eine neue Version ersetzen, um bei TLS 1.2 auf ein neues Sicherheitsprotokoll zu aktualisieren ist unweigerlich defekt, oder es ist wahrscheinlicher, dass Sie die vorhandenen unsicheren Protokolle jahrelang auf Ihrem Server aktiviert lassen müssen, was Ihre Organisation zu einem Ziel für Angriffe macht.

Roger Sanders
quelle
1
Diese Antwort scheint die am meisten durchdachte zu sein. Wenn ich jedoch nichts vermisse, bin ich mir nicht sicher, ob sie vorwärtskompatibel ist, wenn TLS 1.2 unvermeidlich kaputt geht. Nach dem, was ich in meiner .NET 4.7.2-App sehe, wird das SecurityProtocolType.SystemDefaultFlag als ausgewertet. Wenn Sie 0also if (securityProtocols == 0)mit dem Bitwise Inclusive oder Flag für TLS 1.2 prüfen, wird TLS 1.2 immer enthalten, auch wenn es "pausiert" ist, oder? Nicht scharfes Schießen hier. Ich versuche wirklich, den besten Weg vorwärts zu finden.
Griswald_911
Ich habe Ihren Code so geändert, dass er dies enthält, und er scheint zu funktionieren und vorwärtskompatibel zu sein : if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911
@ Griswald_911, ich habe ähnlichen Code in meiner 4.7.2-Konsolenanwendung, und ich habe festgestellt, dass diese Zeile securityProtocols |= SecurityProtocolType.Tls12;(ohne if-Block) SystemDefault nicht verwaltet. Die securityProtocols haben danach nur TLS2. Meinen Sie also, wenn der Wert SystemDefault ist, sollte kein Wert aktualisiert werden? Gehen Sie in Bezug auf die Vorwärtskompatibilität davon aus, dass das Betriebssystem dafür sorgt, dass neuere Protokolle wie TLS 1.3 aktiviert werden?
Yang
@ Yang - Richtig. Die Zeile securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum hat ein [Flags]Attribut, und der SystemDefault-Aufzählungswert ist 0, der SystemDefault-Wert wird entfernt, selbst wenn er zuvor festgelegt wurde. Das Endergebnis ist, dass Sie entweder den SevicePointManager.SecurityProtocol Wert auf 0 oder eine beliebige Kombination der anderen Aufzählungswerte setzen können. Wenn Sie SystemDefault festlegen, können Sie das Protokoll grundsätzlich nicht selbst angeben und das Betriebssystem entscheiden lassen.
Griswald_911
1
@Yang - Der Punkt ist, dass Ihre App nach dem Festlegen des Werts auf SystemDefault alles verwenden sollte, was das Betriebssystem angibt - TLS 1.2 in den neuesten Versionen von Windows 10. Die Idee ist, dass in Zukunft TLS 1.3 wird Standardmäßig sollten Sie Ihre Anwendung nicht ändern müssen, um diese Funktionalität zu erben. Lesen Sie die Dokumentation hier , in der SystemDefault "dem Betriebssystem ermöglicht, das beste zu verwendende Protokoll auszuwählen und nicht sichere Protokolle zu blockieren".
Griswald_911
6

Microsoft hat kürzlich Best Practices veröffentlicht. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Zusammenfassung

Entfernen Sie in .NET Framework 4.7 den Code, der das SecurityProtocol festlegt, damit das Betriebssystem sicherstellt, dass Sie die sicherste Lösung verwenden.

NB: Sie müssen auch sicherstellen, dass die neueste Version von TLS auf Ihrem Betriebssystem unterstützt und aktiviert wird.

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

Weitere Informationen und ältere Frameworks finden Sie unter dem MS-Link.

JohnLBevan
quelle
3
Das Problem ist, dass tls 1.1 und tls 1.2 unter Windows 7 und Server 2008 nicht funktionieren, wenn Sie die Richtlinien befolgen (SecurityProtocolType.SystemDefault beibehalten), da sie in diesen Betriebssystemen ohne eine Registrierungsänderung nicht "aktiviert" sind (was auch immer das bedeutet). Dies macht SystemDefault in der Praxis vom Design her kaputt. Microsoft hat das wirklich durcheinander gebracht.
Osexpert
Schön, danke @osexpert, guter Fang. Ich habe die Antwort dahingehend geändert, dass sie Informationen zu unterstützten Betriebssystemen enthält, sodass es keine Überraschungen für Benutzer mit älteren Betriebssystemen gibt, bei denen es nicht ausreicht, nur auf 4.7 abzuzielen.
JohnLBevan
1
NB: Es gibt auch eine KB, um die neueren Protokolle auf einigen Betriebssystemen zu aktivieren: support.microsoft.com/en-my/help/3140245/…
JohnLBevan
1
Wenn Registrierungseinstellungen keine Option sind, denke ich, ist dies die beste Lösung für .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

Der Vollständigkeit halber finden Sie hier ein Powershell-Skript, mit dem die oben genannten Registrierungsschlüssel festgelegt werden:

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"
qbik
quelle
2

Eine Alternative zur HardcodierungServicePointManager.SecurityProtocol oder zum expliziten SchUseStrongCrypto- Schlüssel wie oben erwähnt:
Sie können .NET anweisen, die Standard-SCHANNEL-Einstellungen mit dem SystemDefaultTlsVersions-Schlüssel zu verwenden,
z.

[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
Alfred
quelle
2

Die BESTE Lösung für dieses Problem scheint ein Upgrade auf mindestens .NET 4.6 oder höher zu sein, bei dem automatisch starke Protokolle sowie starke Chiffren ausgewählt werden.

Wenn Sie kein Upgrade auf .NET 4.6 durchführen können, empfehlen wir die Einstellung

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

Und mit den Registrierungseinstellungen:

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

Dies führt dazu, dass etwas anderes als TLS 1.0 und eine starke Verschlüsselung verwendet werden.

Bei meinen Tests hat nur die Einstellung im Wow6432Node einen Unterschied gemacht, obwohl meine Testanwendung für jede CPU erstellt wurde.

GWC
quelle
Erläuterung: Sie müssen nur den SevicePointManager.SecurityProtocol ODER die Registrierungseinstellungen festlegen. Es ist nicht nötig, beides zu tun. Für meine Anwendung habe ich mich entschieden, nur ServicePointManager.SecurityProtocol festzulegen. Meine Argumentation ist, dass das Festlegen der Registrierung den gesamten Computer betrifft, und ich wollte nicht, dass die Anwendung eines anderen beschädigt wird, da dies von TLS 1.0 abhängt.
GWC
1

Gemäß den Best Practices für Transport Layer Security (TLS) mit .NET Framework : Um sicherzustellen, dass .NET Framework-Anwendungen sicher bleiben, sollte die TLS-Version nicht fest codiert werden. Legen Sie stattdessen die Registrierungsschlüssel fest: SystemDefaultTlsVersions und 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
Benjamin Freitag
quelle
0

Wenn Sie .NET 4.7.1 oder höher verwenden können, wird TLS 1.2 als Mindestprotokoll verwendet, das auf den Funktionen des Betriebssystems basiert. Gemäß Microsoft-Empfehlung:

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.
Yanivhs
quelle
-2

Für Schlüssel: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Wert: SchUseStrongCrypto

Sie müssen den Wert auf 1 setzen.

kgw
quelle
5
Ich denke, Sie werden abgelehnt, weil es die gleiche Antwort ist, die @Jira Mares angeboten hat, aber mit weniger Details
Stuart Siegler