learn.microsoft.com Open in urlscan Pro
2a02:26f0:7100:9a1::3544  Public Scan

Submitted URL: https://support.microsoft.com/en-us/kb/187498
Effective URL: https://learn.microsoft.com/en-US/dotnet/framework/network-programming/tls
Submission: On October 02 via api from GB — Scanned from GB

Form analysis 3 forms found in the DOM

Name: nav-bar-search-formGET /en-us/search/

<form class="nav-bar-search-form" method="GET" name="nav-bar-search-form" role="search" id="nav-bar-search-form" aria-label="Search" action="/en-us/search/">
  <div class="autocomplete" data-bi-name="autocomplete"><!---->
    <div class="field-body control ">
      <input role="combobox" maxlength="100" aria-autocomplete="list" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" id="site-search-input" data-test-id="site-search-input" class="autocomplete-input input input-sm
						
						" type="search" name="terms" aria-expanded="false" aria-owns="ax-129-listbox" aria-controls="ax-129-listbox" aria-activedescendant="" aria-label="Search" aria-describedby="ms--site-search-input-description" placeholder="Search" pattern=".*">
      <span aria-hidden="true" class="icon is-small is-left" hidden="">
        <span class="has-text-primary docon docon-"></span>
      </span>
      <span aria-hidden="true" class="autocomplete-loader loader has-text-primary " hidden=""></span>
      <span hidden="" id="ms--site-search-input-description"> Suggestions will filter as you type </span>
    </div>
    <ul role="listbox" id="ax-129-listbox" data-test-id="site-search-input-listbox" class="autocomplete-suggestions is-vertically-scrollable padding-xxs " aria-label="Suggestions" hidden="">
    </ul>
    <!---->
  </div>
  <!-- mobile safari will not dispatch submit event unless there's a submit button that is not display:none -->
  <button type="submit" class="visually-hidden" tabindex="-1" aria-hidden="true"></button>
  <input name="category" hidden="" value="">
</form>

Name: nav-bar-search-formGET /en-us/search/

<form class="nav-bar-search-form" method="GET" name="nav-bar-search-form" role="search" id="nav-bar-search-form-desktop" aria-label="Search" action="/en-us/search/">
  <div class="autocomplete" data-bi-name="autocomplete"><!---->
    <div class="field-body control has-icons-left">
      <input role="combobox" maxlength="100" aria-autocomplete="list" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" id="site-search-input-desktop" data-test-id="site-search-input-desktop" class="autocomplete-input input input-sm
						control has-icons-left
						" type="search" name="terms" aria-expanded="false" aria-owns="ax-130-listbox" aria-controls="ax-130-listbox" aria-activedescendant="" aria-label="Search" aria-describedby="ms--site-search-input-desktop-description" placeholder="Search"
        pattern=".*">
      <span aria-hidden="true" class="icon is-small is-left">
        <span class="has-text-primary docon docon-search"></span>
      </span>
      <span aria-hidden="true" class="autocomplete-loader loader has-text-primary " hidden=""></span>
      <span hidden="" id="ms--site-search-input-desktop-description"> Suggestions will filter as you type </span>
    </div>
    <ul role="listbox" id="ax-130-listbox" data-test-id="site-search-input-desktop-listbox" class="autocomplete-suggestions is-vertically-scrollable padding-xxs " aria-label="Suggestions" hidden="">
    </ul>
    <!---->
  </div>
  <!-- mobile safari will not dispatch submit event unless there's a submit button that is not display:none -->
  <button type="submit" class="visually-hidden" tabindex="-1" aria-hidden="true"></button>
  <input name="category" hidden="" value="">
</form>

javascript:

<form action="javascript:" role="search" aria-label="Search" class="margin-bottom-xxs"><label class="visually-hidden" for="ax-146">Search</label>
  <div class="autocomplete display-block" data-bi-name="autocomplete"><!---->
    <div class="field-body control has-icons-left">
      <input role="combobox" maxlength="100" aria-autocomplete="list" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" id="ax-146" data-test-id="ax-146" class="autocomplete-input input input-sm
						control has-icons-left
						width-full" type="text" aria-expanded="false" aria-owns="ax-147-listbox" aria-controls="ax-147-listbox" aria-activedescendant="" aria-describedby="ms--ax-146-description" placeholder="Filter by title" pattern=".*">
      <span aria-hidden="true" class="icon is-small is-left">
        <span class="has-text-primary docon docon-filter-settings"></span>
      </span>
      <span aria-hidden="true" class="autocomplete-loader loader has-text-primary " hidden=""></span>
      <span hidden="" id="ms--ax-146-description"> Suggestions will filter as you type </span>
    </div>
    <ul role="listbox" id="ax-147-listbox" data-test-id="ax-146-listbox" class="autocomplete-suggestions is-vertically-scrollable padding-xxs " aria-label="Suggestions" hidden="">
    </ul>
    <!---->
  </div>
</form>

Text Content

Skip to main content

We use optional cookies to improve your experience on our websites, such as
through social media connections, and to display personalized advertising based
on your online activity. If you reject optional cookies, only cookies necessary
to provide you the services will be used. You may change your selection by
clicking “Manage Cookies” at the bottom of the page. Privacy Statement
Third-Party Cookies

Accept Reject Manage cookies

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security
updates, and technical support.

Download Microsoft Edge More info about Internet Explorer and Microsoft Edge
Documentation
Global navigation
 * Learn
   
 * Documentation
   
 * Training
   
 * Credentials
   
 * Q&A
   
 * Code Samples
   
 * Assessments
   
 * Shows
   
 * More
     
   * Documentation
     
   * Training
     
   * Credentials
     
   * Q&A
     
   * Code Samples
     
   * Assessments
     
   * Shows
     
   

Suggestions will filter as you type
Suggestions will filter as you type
Search
Sign in

 * Profile
 * Settings

Sign out
.NET
   
 * Languages
     
   * C#
     
   * F#
     
   * Visual Basic
     
   
 * Features
     
   * Fundamentals
     
   * Tools and diagnostics
     
   * Migrate from .NET Framework
     
   * Compatibility
     
   * Advanced programming
     
   * DevOps and testing
     
   * Security
     
   * Data access
     
   
 * Workloads
     
   * Web
     
   * Mobile
     
   * Cloud
     
   * Desktop
       
     * .NET Multi-platform App UI (.NET MAUI)
       
     * Windows Presentation Foundation
       
     * Windows Forms
       
     * Universal Windows apps
       
     
   * Machine Learning & Data
       
     * ML.NET
       
     * Entity Framework
       
     
   
 * APIs
     
   * .NET
     
   * .NET Framework
     
   * .NET Multi-platform App UI (.NET MAUI)
     
   * ASP.NET
     
   * ML.NET
     
   
 * Resources
     
   * Library guidance
     
   * What is .NET?
     
   * .NET architecture guides
     
   * Learning materials
     
   * Downloads
     
   * Community
     
   * Support
     
   * Blog
     
   
 * More
     
   * Languages
       
     * C#
       
     * F#
       
     * Visual Basic
       
     
   * Features
       
     * Fundamentals
       
     * Tools and diagnostics
       
     * Migrate from .NET Framework
       
     * Compatibility
       
     * Advanced programming
       
     * DevOps and testing
       
     * Security
       
     * Data access
       
     
   * Workloads
       
     * Web
       
     * Mobile
       
     * Cloud
       
     * Desktop
         
       * .NET Multi-platform App UI (.NET MAUI)
         
       * Windows Presentation Foundation
         
       * Windows Forms
         
       * Universal Windows apps
         
       
     * Machine Learning & Data
         
       * ML.NET
         
       * Entity Framework
         
       
     
   * APIs
       
     * .NET
       
     * .NET Framework
       
     * .NET Multi-platform App UI (.NET MAUI)
       
     * ASP.NET
       
     * ML.NET
       
     
   * Resources
       
     * Library guidance
       
     * What is .NET?
       
     * .NET architecture guides
       
     * Learning materials
       
     * Downloads
       
     * Community
       
     * Support
       
     * Blog
       
     
   

 1. Download .NET

Table of contents Exit focus mode

Search
Suggestions will filter as you type
 * Configuring Internet Applications
 * Network Tracing in the .NET Framework
 * Cache Management for Network Applications
 * FTP
 * UDP
 * Security in Network Programming
   * Security in Network Programming
   * Transport Layer Security (TLS) best practices
   * Using Secure Sockets Layer
   * Internet Authentication
   * Web and Socket Permissions
 * Best Practices for System.Net Classes
 * Peer Name Resolution Protocol
 * Peer-to-Peer Collaboration
 * Integrated Windows Authentication with Extended Protection

Download PDF
    
 1. Learn
    
    
 2. .NET
    
    
 3. .NET Framework
    
    
 4. Network programming
    

    
 1. Learn
    
    
 2. .NET
    
    
 3. .NET Framework
    
    
 4. Network programming
    

Read in English Add
Table of contents Read in English Add Edit Print

Twitter LinkedIn Facebook Email
Table of contents


TRANSPORT LAYER SECURITY (TLS) BEST PRACTICES WITH THE .NET FRAMEWORK

 * Article
 * 07/18/2023
 * 18 contributors

Feedback



IN THIS ARTICLE

     
 1.  Audit your code and make code changes
     
 2.  If your app targets .NET Framework 4.7 or later versions
     
 3.  If your app targets a .NET Framework version earlier than 4.7
     
 4.  If your app targets .NET Framework 3.5
     
 5.  Configure security via AppContext switches (for .NET Framework 4.6 or later
     versions)
     
 6.  Configure security via the Windows Registry
     
 7.  Configure Schannel protocols in the Windows Registry
     
 8.  The SCH_USE_STRONG_CRYPTO flag
     
 9.  Security updates
     
 10. Support for TLS 1.2
     

Show 6 more

The Transport Layer Security (TLS) protocol is an industry standard designed to
help protect the privacy of information communicated over the Internet. TLS 1.2
is a standard that provides security improvements over previous versions. TLS
1.2 will eventually be replaced by the newest released standard TLS 1.3 which is
faster and has improved security. This article presents recommendations to
secure .NET Framework applications that use the TLS protocol.

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.

This document targets developers who are:

 * Directly using the System.Net APIs (for example, System.Net.Http.HttpClient
   and System.Net.Security.SslStream).
 * Directly using WCF clients and services using the System.ServiceModel
   namespace.

Consider the following recommendations:

 * For TLS 1.2, target .NET Framework 4.7 or later versions on your apps, and
   target .NET Framework 4.7.1 or later versions on your WCF apps.
 * For TLS 1.3, target .NET Framework 4.8 or later.
 * Do not specify the TLS version. Configure your code to let the OS decide on
   the TLS version.
 * Perform a thorough code audit to verify you're not specifying a TLS or SSL
   version.

When your app lets the OS choose the TLS version:

 * It automatically takes advantage of new protocols added in the future, such
   as TLS 1.3.
 * The OS blocks protocols that are discovered not to be secure.

The section Audit your code and make code changes covers auditing and updating
your code.

This article explains how to enable the strongest security available for the
version of .NET Framework that your app targets and runs on. When an app
explicitly sets a security protocol and version, it opts out of any other
alternative, and opts out of .NET Framework and OS default behavior. If you want
your app to be able to negotiate a TLS 1.2 connection, explicitly setting to a
lower TLS version prevents a TLS 1.2 connection.

If you can't avoid hardcoding a protocol version, we strongly recommend that you
specify TLS 1.2. For guidance on identifying and removing TLS 1.0 dependencies,
download the Solving the TLS 1.0 Problem white paper.

WCF Supports TLS 1.0, 1.1, and 1.2 as the default in .NET Framework 4.7.
Starting with .NET Framework 4.7.1, WCF defaults to the operating system
configured version. If an application is explicitly configured with
SslProtocols.None, WCF uses the operating system default setting when using the
NetTcp transport.

You can ask questions about this document in the GitHub issue Transport Layer
Security (TLS) best practices with the .NET Framework.


AUDIT YOUR CODE AND MAKE CODE CHANGES

For ASP.NET applications, inspect the <system.web><httpRuntime targetFramework>
element of web.config to verify you're using the intended version of the .NET
Framework.

For Windows Forms and other applications, see How to: Target a Version of the
.NET Framework.

Use the following sections to verify you're not using a specific TLS or SSL
version.


IF YOUR APP TARGETS .NET FRAMEWORK 4.7 OR LATER VERSIONS

The following sections show how to verify you're not using a specific TLS or SSL
version.


FOR HTTP NETWORKING

ServicePointManager, using .NET Framework 4.7 and later versions, will use the
default security protocol configured in the OS. To get the default OS choice, if
possible, don't set a value for the ServicePointManager.SecurityProtocol
property, which defaults to SecurityProtocolType.SystemDefault.

Because the SecurityProtocolType.SystemDefault setting causes the
ServicePointManager to use the default security protocol configured by the
operating system, your application may run differently based on the OS it's run
on. For example, Windows 7 SP1 uses TLS 1.0 while Windows 8 and Windows 10 use
TLS 1.2.

The remainder of this article is not relevant when targeting .NET Framework 4.7
or later versions for HTTP networking.


FOR TCP SOCKETS NETWORKING

SslStream, using .NET Framework 4.7 and later versions, defaults to the OS
choosing the best security protocol and version. To get the default OS best
choice, if possible, don't use the method overloads of SslStream that take an
explicit SslProtocols parameter. Otherwise, pass SslProtocols.None. We recommend
that you don't use Default; setting SslProtocols.Default forces the use of SSL
3.0 /TLS 1.0 and prevents TLS 1.2.

Don't set a value for the SecurityProtocol property (for HTTP networking).

Don't use the method overloads of SslStream that take an explicit SslProtocols
parameter (for TCP sockets networking). When you retarget your app to .NET
Framework 4.7 or later versions, you'll be following the best practices
recommendation.

The remainder of this topic is not relevant when targeting .NET Framework 4.7 or
later versions for TCP sockets networking.




FOR WCF TCP TRANSPORT USING TRANSPORT SECURITY WITH CERTIFICATE CREDENTIALS

WCF uses the same networking stack as the rest of .NET Framework.

If you're targeting 4.7.1, WCF is configured to allow the OS to choose the best
security protocol by default unless explicitly configured:

 * In your application configuration file.
 * Or, in your application in the source code.

By default, .NET Framework 4.7 and later versions are configured to use TLS 1.2
and allow connections using TLS 1.1 or TLS 1.0. Configure WCF to allow the OS to
choose the best security protocol by configuring your binding to use
SslProtocols.None. This can be set on SslProtocols. SslProtocols.None can be
accessed from Transport. NetTcpSecurity.Transport can be accessed from Security.

If you're using a custom binding:

 * Configure WCF to allow the OS to choose the best security protocol by setting
   SslProtocols to use SslProtocols.None.
 * Or configure the protocol used with the configuration path
   system.serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols.

If you're not using a custom binding and you're setting your WCF binding using
configuration, set the protocol used with the configuration path
system.serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols.


FOR WCF MESSAGE SECURITY WITH CERTIFICATE CREDENTIALS

.NET Framework 4.7 and later versions by default use the protocol specified in
the SecurityProtocol property. When the AppContextSwitch
Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols is
set to true, WCF chooses the best protocol, up to TLS 1.0.


IF YOUR APP TARGETS A .NET FRAMEWORK VERSION EARLIER THAN 4.7

Audit your code to verify you're not setting a specific TLS or SSL version using
the following sections.


FOR .NET FRAMEWORK 4.6 - 4.6.2 AND NOT WCF

Set the DontEnableSystemDefaultTlsVersions AppContext switch to false. See
Configuring security via AppContext switches.


FOR WCF USING .NET FRAMEWORK 4.6 - 4.6.2 USING TCP TRANSPORT SECURITY WITH
CERTIFICATE CREDENTIALS

You must install the latest OS patches. See Security updates.

The WCF framework automatically chooses the highest protocol available up to TLS
1.2 unless you explicitly configure a protocol version. For more information,
see the preceding section For WCF TCP transport using transport security with
certificate credentials.


FOR .NET FRAMEWORK 3.5 - 4.5.2 AND NOT WCF

We recommend you upgrade your app to .NET Framework 4.7 or a later version. If
you cannot upgrade, take the following steps:

 * Set the SchUseStrongCrypto and SystemDefaultTlsVersions registry keys to 1.
   See Configuring security via the Windows Registry. .NET Framework 3.5
   supports the SchUseStrongCrypto flag only when an explicit TLS value is
   passed.

 * If you're running on .NET Framework 3.5, you need to install a hot patch so
   that TLS 1.2 can be specified by your program:
   
   KB3154518 Reliability Rollup HR-1605 - Support for TLS System Default
   Versions included in the .NET Framework 3.5.1 on Windows 7 SP1 and Server
   2008 R2 SP1 KB3154519 Reliability Rollup HR-1605 - Support for TLS System
   Default Versions included in the .NET Framework 3.5 on Windows Server 2012
   KB3154520 Reliability Rollup HR-1605 -Support for TLS System Default Versions
   included in the .NET Framework 3.5 on Windows 8.1 and Windows Server 2012 R2
   KB3156421 1605 Hotfix rollup 3154521 for the .NET Framework 4.5.2 and 4.5.1
   on Windows


FOR WCF USING .NET FRAMEWORK 3.5 - 4.5.2 USING TCP TRANSPORT SECURITY WITH
CERTIFICATE CREDENTIALS

These versions of the WCF framework are hardcoded to use values SSL 3.0 and TLS
1.0. These values cannot be changed. You must update and retarget to NET
Framework 4.6 or later versions to use TLS 1.1 and 1.2.


IF YOUR APP TARGETS .NET FRAMEWORK 3.5

If you must explicitly set a security protocol instead of letting .NET or the OS
pick the security protocol, add SecurityProtocolTypeExtensions and
SslProtocolsExtension enumerations to your code. SecurityProtocolTypeExtensions
and SslProtocolsExtension include values for Tls12, Tls11, and the SystemDefault
value. For more information, see Support for TLS System Default Versions
included in .NET Framework 3.5 on Windows 8.1 and Windows Server 2012 R2.




CONFIGURE SECURITY VIA APPCONTEXT SWITCHES (FOR .NET FRAMEWORK 4.6 OR LATER
VERSIONS)

The AppContext switches described in this section are relevant if your app
targets, or runs on, .NET Framework 4.6 or later versions. Whether by default,
or by setting them explicitly, the switches should be false if possible. If you
want to configure security via one or both switches, then don't specify a
security protocol value in your code; doing so would override the switch(es).

The switches have the same effect whether you're doing HTTP networking
(ServicePointManager) or TCP sockets networking (SslStream).


SWITCH.SYSTEM.NET.DONTENABLESCHUSESTRONGCRYPTO

A value of false for Switch.System.Net.DontEnableSchUseStrongCrypto causes your
app to use strong cryptography. A value of false for
DontEnableSchUseStrongCrypto uses more secure network protocols (TLS 1.2 and TLS
1.1) and blocks protocols that are not secure. For more info, see The
SCH_USE_STRONG_CRYPTO flag. A value of true disables strong cryptography for
your app. This switch affects only client (outgoing) connections in your
application.

If your app targets .NET Framework 4.6 or later versions, this switch defaults
to false. That's a secure default, which we recommend. If your app runs on .NET
Framework 4.6, but targets an earlier version, the switch defaults to true. In
that case, you should explicitly set it to false.

DontEnableSchUseStrongCrypto should only have a value of true if you need to
connect to legacy services that don't support strong cryptography and can't be
upgraded.


SWITCH.SYSTEM.NET.DONTENABLESYSTEMDEFAULTTLSVERSIONS

A value of false for Switch.System.Net.DontEnableSystemDefaultTlsVersions causes
your app to allow the operating system to choose the protocol. A value of true
causes your app to use protocols picked by the .NET Framework.

If your app targets .NET Framework 4.7 or later versions, this switch defaults
to false. That's a secure default that we recommend. If your app runs on .NET
Framework 4.7 or later versions, but targets an earlier version, the switch
defaults to true. In that case, you should explicitly set it to false.


SWITCH.SYSTEM.SERVICEMODEL.DISABLEUSINGSERVICEPOINTMANAGERSECURITYPROTOCOLS

A value of false for
Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols
causes your application to use the value defined in
ServicePointManager.SecurityProtocols for message security using certificate
credentials. A value of true uses the highest protocol available, up to TLS1.0

For applications targeting .NET Framework 4.7 and later versions, this value
defaults to false. For applications targeting .NET Framework 4.6.2 and earlier,
this value defaults to true.


SWITCH.SYSTEM.SERVICEMODEL.DONTENABLESYSTEMDEFAULTTLSVERSIONS

A value of false for
Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions sets the default
configuration to allow the operating system to choose the protocol. A value of
true sets the default to the highest protocol available, up to TLS1.2.

For applications targeting .NET Framework 4.7.1 and later versions, this value
defaults to false. For applications targeting .NET Framework 4.7 and earlier,
this value defaults to true.

For more information about TLS protocols, see Mitigation: TLS Protocols. For
more information about AppContext switches, see <AppContextSwitchOverrides>
Element.


CONFIGURE SECURITY VIA THE WINDOWS REGISTRY

Warning

Setting registry keys affects all applications on the system. Use this option
only if you are in full control of the machine and can control changes to the
registry.

If setting one or both AppContext switches isn't an option, you can control the
security protocols that your app uses with the Windows Registry keys described
in this section. You might not be able to use one or both the AppContext
switches if your app runs on .NET Framework 4.5.2 or earlier versions, or if you
can't edit the configuration file. If you want to configure security with the
registry, don't specify a security protocol value in your code; doing so
overrides the registry setting.

The names of the registry keys are similar to the names of the corresponding
AppContext switches but without a DontEnable prepended to the name. For example,
the AppContext switch DontEnableSchUseStrongCrypto is the registry key called
SchUseStrongCrypto.

These keys are available in all .NET Framework versions for which there's a
recent security patch. See Security updates.

All of the registry keys described below have the same effect whether you're
doing HTTP networking (ServicePointManager) or TCP sockets networking
(SslStream).


SCHUSESTRONGCRYPTO

The HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>:
SchUseStrongCrypto registry key has a value of type DWORD. A value of 1 causes
your app to use strong cryptography. The strong cryptography uses more secure
network protocols (TLS 1.2 and TLS 1.1) and blocks protocols that aren't secure.
A value of 0 disables strong cryptography. For more information, see The
SCH_USE_STRONG_CRYPTO flag. This registry setting affects only client (outgoing)
connections in your application.

If your app targets .NET Framework 4.6 or later versions, this key defaults to a
value of 1. That's a secure default that we recommend. If your app targets .NET
Framework 4.5.2 or earlier versions, the key defaults to 0. In that case, you
should explicitly set its value to 1.

This key should only have a value of 0 if you need to connect to legacy services
that don't support strong cryptography and can't be upgraded.


SYSTEMDEFAULTTLSVERSIONS

The HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Microsoft\.NETFramework\<VERSION>:
SystemDefaultTlsVersions registry key has a value of type DWORD. A value of 1
causes your app to allow the operating system to choose the protocol. A value of
0 causes your app to use protocols picked by the .NET Framework.

<VERSION> must be v4.0.30319 (for .NET Framework 4 and above) or v2.0.50727 (for
.NET Framework 3.5).

If your app targets .NET Framework 4.7 or later versions, this key defaults to a
value of 1. That's a secure default that we recommend. If your app targets .NET
Framework 4.6.1 or earlier versions, the key defaults to 0. In that case, you
should explicitly set its value to 1.

For more info, see Cumulative Update for Windows 10 Version 1511 and Windows
Server 2016 Technical Preview 4: May 10, 2016.

For more information with .NET Framework 3.5.1, see Support for TLS System
Default Versions included in .NET Framework 3.5.1 on Windows 7 SP1 and Server
2008 R2 SP1.

The following .REG file sets the registry keys and their variants to their most
safe values:

text Copy


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



CONFIGURE SCHANNEL PROTOCOLS IN THE WINDOWS REGISTRY

You can use the registry for fine-grained control over the protocols that your
client and/or server app negotiates. Your app's networking goes through Schannel
(which is another name for Secure Channel. By configuring Schannel, you can
configure your app's behavior.

Start with the
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
registry key. Under that key you can create any subkeys in the set SSL 2.0, SSL
3.0, TLS 1.1, and TLS 1.2. Under each of those subkeys, you can create subkeys
Client and/or Server. Under Client and Server, you can create DWORD values
DisabledByDefault (0 or 1) and Enabled (0 or 1).


THE SCH_USE_STRONG_CRYPTO FLAG

When it's enabled (by default, by an AppContext switch, or by the Windows
Registry), .NET Framework uses the SCH_USE_STRONG_CRYPTO flag when your app
initiates a TLS connection to a server. .NET Framework passes the flag to
Schannel to instruct it to disable known weak cryptographic algorithms, cipher
suites, and TLS/SSL protocol versions that may be otherwise enabled for better
interoperability. For more information, see:

 * Secure Channel
 * SCHANNEL_CRED structure

The SCH_USE_STRONG_CRYPTO flag is also passed to Schannel for client (outgoing)
connections when you explicitly use the Tls11 or Tls12 enumerated values of
SecurityProtocolType or SslProtocols. The SCH_USE_STRONG_CRYPTO flag is used
only for connections where your application acts the role of the client. You can
disable weak protocols and algorithms when your applications acts the role of
the server by configuring the machine-wide Schannel registry settings.


SECURITY UPDATES

The best practices in this article depend on recent security updates being
installed. These updates include the ability to use advanced .NET Framework 4.7
and later features. Recent security updates are important if your app runs on
.NET Framework 4.7 and later versions (even if it targets an earlier version).

To update .NET Framework to allow the operating system to choose the best
version of TLS to use, you must install at least:

 * The .NET Framework August 2017 Preview of Quality Rollup.
 * Or the .NET Framework September 2017 Security and Quality Rollup.

See also:

 * .NET Framework Versions and Dependencies
 * How to: Determine Which .NET Framework Versions Are Installed.


SUPPORT FOR TLS 1.2

For your app to negotiate TLS 1.2, the OS and the .NET Framework version both
need to support TLS 1.2.

Operating system requirements to support TLS 1.2

To enable or re-enable TLS 1.2 and/or TLS 1.1 on a system that supports them,
see Transport Layer Security (TLS) registry settings.

OS TLS 1.2 support Windows 10
Windows Server 2016 Supported, and enabled by default. Windows 8.1
Windows Server 2012 R2 Supported, and enabled by default. Windows 8.0
Windows Server 2012 Supported, and enabled by default. Windows 7 SP1
Windows Server 2008 R2 SP1 Supported, but not enabled by default. See the
Transport Layer Security (TLS) registry settings web page for details on how to
enable TLS 1.2. 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.

For information about which TLS/SSL protocols are enabled by default on each
version of Windows, see Protocols in TLS/SSL (Schannel SSP).

Requirements to support TLS 1.2 with .NET Framework 3.5

This table shows the OS update you'll need to support TLS 1.2 with .NET
Framework 3.5. We recommend you apply all OS updates.

OS Minimum update needed to support TLS 1.2 with .NET Framework 3.5 Windows 10
Windows Server 2016 Cumulative Update for Windows 10 Version 1511 and Windows
Server 2016 Technical Preview 4: May 10, 2016 Windows 8.1
Windows Server 2012 R2 Support for TLS System Default Versions included in the
.NET Framework 3.5 on Windows 8.1 and Windows Server 2012 R2 Windows 8.0
Windows Server 2012 Support for TLS System Default Versions included in the .NET
Framework 3.5 on Windows Server 2012 Windows 7 SP1
Windows Server 2008 R2 SP1 Support for TLS System Default Versions included in
the .NET Framework 3.5.1 on Windows 7 SP1 and Server 2008 R2 SP1 Windows Server
2008 Support for TLS System Default Versions included in the .NET Framework 2.0
SP2 on Windows Vista SP2 and Server 2008 SP2 Windows Vista Not supported



Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create
and review issues and pull requests. For more information, see our contributor
guide.

.NET feedback

The .NET documentation is open source. Provide feedback here.

Open a documentation issue Provide product feedback


FEEDBACK

Submit and view feedback for

This product This page
View all page feedback

--------------------------------------------------------------------------------


ADDITIONAL RESOURCES





English (United States)
Theme
 * Light
 * Dark
 * High contrast

 * Manage cookies
 * Previous Versions
 * Blog
 * Contribute
 * Privacy
 * Terms of Use
 * Trademarks
 * © Microsoft 2023


ADDITIONAL RESOURCES






IN THIS ARTICLE



English (United States)
Theme
 * Light
 * Dark
 * High contrast

 * Manage cookies
 * Previous Versions
 * Blog
 * Contribute
 * Privacy
 * Terms of Use
 * Trademarks
 * © Microsoft 2023