Secure Cipher Suites allowed, ordering for TLS 1.2, 1.3 with general Schannel security guidance for Windows 1x, Server 2022
The following guidance is to allow only the strongest cipher suites for TLS 1.2 and TLS 1.3 that also are allowed by the .Net setting of SCH_USE_STRONG_CRYPTO and to eliminate other cryptographic elements that are weak on insecure.
You can check to determine the security status of a cipher suite at https://ciphersuite.info/
Note: The registry settings at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL" are unsupported except for the Protocols path, and should be controlled by the deliberate selection of cipher suites using PowerShell TLS cmdlets or via Group Policy as the preferred method of configuration.
First business:
Security notes regarding insecure cryptographic elements:
It is a REALLY good idea to disabled all algorithms and protocols that are insecure
Review cryptographic suite elements and remove known compromised elements.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010003.Functions
Example data:
RSAE-PSS/SHA256
RSAE-PSS/SHA384
RSAE-PSS/SHA512
RSA/SHA256
RSA/SHA384
ECDSA/SHA256
ECDSA/SHA384
RSA/SHA512
ECDSA/SHA512
(the highlighted line items should be deleted as they are compromised or contain weak cryptographic elements)
How to Restrict cryptographic algorithms and protocols - Windows Server | Microsoft Docs
Current (8/2022) list of weak or insecure cryptographic elements
The Secure Hash Algorithm 1 (SHA1 or SHA) has been shown as insecure as of 2017. Review shattered.io for details.
Data Encryption Standard (DES) is weak due to its short key-lengths of 40 or 65-Bit. In 2005 the National Institute of Standards and Technology has withdrawn DES as a standard.
Triple-DES is still utilized as a secure symmetric-key encryption, but a number of standardizations bodies and projects have deprecate Triple-DES even though it has not broken, in the past, it has been shown to suffer from several vulnerabilities.
Cipher Block Chaining (CBC) was demonstrated in 2013 by researchers utilizing a timing attack against several TLS implementations using the encryption algorithm. Also, CBC mode is vulnerable to plain-text attacks in TLS 1.0, SSL 3.0 and lower. A fix has been introduced with TLS 1.2 in the form of the GCM mode which is not vulnerable to the BEAST attack. GCM should be preferred over CBC. Review isg.rhul.ac.uk for more details.
Anonymous (ANON) key exchange is vulnerable to Man in the Middle attacks
NULL Authentication uses no authentication and does not provide integrity.
NULL Encryption uses no encryption at all which does not provide any confidentiality.
Rivest Cipher 4 (RC4) has officially been prohibited by the IETF for use in TLS in RFC 7465 and is considered insecure. Microsoft security advisory: Update for disabling RC4
Message Digest 5 (MD5) has multiple vulnerabilities and is considered insecure.
ShangMi 3 (SM3) hashing algorithm is a Chinese algorithm, which will be or is already mandatory for TLS encrypted connections in China. The security of this algorithm is not proven, and its use is not recommended by the IETF. For further details review https://tools.ietf.org/html/rfc8998
ShangMi 4 (SM4) encryption algorithm is a Chinese algorithm, which will be or is already mandatory for TLS encrypted connections in China. The security of this algorithm is not proven, and its use is not recommended by the IETF. For further details review https://tools.ietf.org/html/rfc8998
Diffie-Hellman (DH) is a Non-ephemeral Key Exchange and does not support Perfect Forward Secrecy (PFS) which is recommended, so an attacker is unable to decrypt the complete communication stream.
Elliptic Curve Diffie-Hellman (ECDH) is a Non-ephemeral Key Exchange and does not support Perfect Forward Secrecy (PFS) which is recommended, so an attacker is unable to decrypt the complete communication stream.
Kerberos 5 (KRB5) is a Non-ephemeral Key Exchange and does not support Perfect Forward Secrecy (PFS) which is recommended, so an attacker is unable to decrypt the complete communication stream.
Rivest Cipher 2 (RC2) A related-key attack discovered in 1997 renders it insecure. For further details review https://www.schneier.com/wp-content/uploads/2016/02/paper-relatedkey.pdf
Notes: Windows TLS stack never supported non-ephemeral (EC)DH. The only non-PFS cipher suites supported in schannel are TLS_RSA
SSL/TLS insecure protocols which should be disabled for client and server on every machine:
Multi-Protocol Unified Hello
SSL 2.0
SSL 3.0
TLS 1.0
TLS 1.1
Schannel registry settings - Transport Layer Security (TLS) registry settings | Microsoft Docs - The registry values that are being utilized and supported.
.Net security considerations
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, TLS 1.1, and TLS 1.0) and blocks protocols that are not 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:
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
Configuring 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.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), the .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:
The SCH_USE_STRONG_CRYPTO flag is also passed to Schannel for client (outgoing) connections when you explicitly use the Tls (TLS 1.0), 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.
Performance notes:
RSA Authentication has been reported that servers using the algorithm with >=3072-bit keys could experience large performance issues leading to connection timeouts and even service unavailability if a large numbed clients open simultaneous connections.
Review the current cipher suites being utilized on the machine.
Get-TlsCipherSuite | Format-Table Name
Disabled insecure cipher suites - Note: The cipher suites being disabled in this list all have insecure or weak features.
PowerShell Command to disable Cipher Suite |
---|
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_DSS_WITH_DES_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" |
Disable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_EXPORT_WITH_RC4_40_MD5" |
Disable-TlsCipherSuite -Name "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_3DES_EDE_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_DES_CBC_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_NULL_MD5" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_NULL_SHA" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_RC4_128_MD5" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_RC4_128_SHA" |
Disable-TlsCipherSuite -Name "TLS_SHA256_SHA256" |
Disable-TlsCipherSuite -Name "TLS_SHA384_SHA384" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_GCM_SHA384" |
Disable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_GCM_SHA256" |
Enabling or disabling additional cipher suites
You can disable certain specific ciphers by removing them from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002 in the registry.
Note: The "SSL\00010002" registry key is controlled by a Group Policy that can be set locally or in a Group Policy Object. This designates the cipher suites that are enabled and the order which they are presented.
To configure the SSL Cipher Suite Order group policy setting
-
At a command prompt, enter gpedit.msc a. The Group Policy Object Editor appears. 2.Expand Computer Configuration, Administrative Templates, Network, and then click SSL Configuration Settings.
-
Under SSL Configuration Settings, click the SSL Cipher Suite Order setting.
-
In the SSL Cipher Suite Order pane, scroll to the bottom of the pane.
-
Follow the instructions labeled How to modify this setting. a. String for GPO for above cipher suite order. TLS_CHACHA20_POLY1305_SHA256,TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_PSK_WITH_AES_256_GCM_SHA384,TLS_PSK_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
-
It is necessary to restart the computer after modifying this setting for the changes to take effect.
Screenshot of the Registry Editor showing the Edit Multi-String dialog box for the 00010002 folder.
To enable a cipher suite, add its string value to the Functions multi-string value key or preferably to the policy "SSL Configuration Settings". As an example, if we want to enable TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521 then we would add it to the string.
For a full list of supported Cipher suites see Cipher Suites in TLS/SSL (Schannel SSP). This document provides a table of suites that are enabled by default and those that are supported but not enabled by default. To prioritize the cipher suites, see Prioritizing Schannel Cipher Suites.
The following is a list of cipher suites that are Windows supports for TLS 1.2 and TLS 1.3, are allowed by SCH_USE_STRONG_CRYPTO and support Perfect Forward Secrecy (PFS) and that have no known weakness or insecurity in any element as of 7/2022.
Cipher suite string | Allowed by SCH_USE_STRONG_CRYPTO | TLS/SSL Protocol versions |
---|---|---|
TLS_CHACHA20_POLY1305_SHA256 | Yes | TLS 1.3 |
TLS_AES_128_GCM_SHA256 | Yes | TLS 1.3 |
TLS_AES_256_GCM_SHA384 | Yes | TLS 1.3 |
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | Yes | TLS 1.2 |
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | Yes | TLS 1.2 |
TLS_PSK_WITH_AES_256_GCM_SHA384 | Yes | TLS 1.2 |
TLS_PSK_WITH_AES_128_GCM_SHA256 | Yes | TLS 1.2 |
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | Yes | TLS 1.2 |
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | Yes | TLS 1.2 |
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 | Yes | TLS 1.2 |