Default SecurityProtocol in .NET 4.5
与最多支持
1 2 | System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; |
除了代码更改之外,还有什么方法可以更改这个默认值吗?
最后,
我的动机是在客户端删除对
更新:看
不过,我决定将所有应用程序升级到
这将向各种API和服务发出出站请求,使其不降级到
这种方法听起来合理还是过度杀伤力?我有许多应用程序需要更新,我希望将来能证明它们,因为我听说甚至
作为向API发出出站请求的客户端,在注册表中禁用ssl3是否在.NET框架中也有影响?我看到在默认情况下,没有启用TLS 1.1和1.2,我们必须通过注册表启用它吗?请访问http://support.microsoft.com/kb/245030。
经过一点调查,我相信注册表设置不会有影响,因为它们适用于IIS(服务器子项)和浏览器(客户端子项)。
很抱歉,这篇文章变成了多个问题,接下来是"可能"的答案。
一些留下评论的人指出,将
要在不影响其他协议的情况下打开TLS 1.1和1.2:
1 2 | System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; |
注意使用
要在不影响其他协议的情况下关闭SSL3:
1 | System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3; |
两个.NET
但是,如果在同一环境中安装了
我通过观察与
1 2 | ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072; |
参考文献:
1 2 3 4 5 6 7 8 9 10 11 | namespace System.Net { [System.Flags] public enum SecurityProtocolType { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } } |
如果您试图在仅安装了
Unhandled Exception: System.NotSupportedException: The requested security protocol is not supported.
at System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType v
alue)
但是,我不推荐这种"黑客",因为将来的补丁等可能会破坏它。*
因此,我决定取消对
将以下内容添加到bootstrapping代码中,以覆盖默认和将来的证明:
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
*如果这个黑客是错误的,有人会纠正我,但初步测试我看是有效的。
您可以覆盖以下注册表中的默认行为:
1 2 3 4 | Key : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 Value: SchUseStrongCrypto Type: REG_DWORD Data : 1 |
和
1 2 3 4 | Key : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319 Value: SchUseStrongCrypto Type: REG_DWORD Data : 1 |
具体见
创建扩展名为
1 2 3 4 5 6 7 | 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 |
或从以下来源下载:
https://tls1test.salesforce.com/s/net40-enable-tls-1_2.reg
双击以安装…
我发现,当我只指定TLS 1.2时,它仍将协商到1.1。
我已经在.NET 4.5 Web应用程序的global.asax启动方法中指定了这一点。
经过一番斗争,注册表更改机制对我有效。实际上,我的应用程序以32位运行。所以我必须改变路径下的值。
1 | HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319 |
值类型必须是双字且值大于0。最好使用1.。
我的客户将tls从1.0升级到1.2时遇到问题。我的应用程序正在使用.NET Framework 3.5并在服务器上运行。所以我就这样解决了:
在调用httpwebrequest.getresponse()之前,请添加以下命令:
1 | ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12; |
通过添加2个新类来扩展2个DLL:System.net和System.Security.Authentication
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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; } } |
下载批处理:
- 对于Windows 2008 R2:windows6.1-kb3154518-x64.msu
- 对于Windows 2012r2:windows8.1-kb3154520-x64.msu
有关下载批次和更多详细信息,请参见以下内容:
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
以下代码将:
- 支持打印的协议
- 打印可用协议
- 如果平台支持TLS1.2,且未启用,则启用该TLS1.2。
- 如果启用了SSL3,则禁用它
- 打印最终结果
常数:
- 48是SSL3
- 192是TLS1
- 768是TLS1.1
- 3072是TLS1.2
其他协议不会受到影响。这使得它与未来的协议(TLS1.3等)兼容。
代码1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // 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); |
产量
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
我在.NET 4.5.2下运行,我对这些答案都不满意。当我正在与一个支持TLS 1.2的系统交谈时,看到SSL3、TLS 1.0和TLS 1.1都已损坏,无法安全使用,我不想启用这些协议。在.NET 4.5.2下,ssl3和tls 1.0协议都默认启用,我可以通过检查
1 2 3 4 5 6 7 8 9 10 | 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; } |
此代码将检测何时启用了已知的不安全协议,在这种情况下,我们将删除这些不安全协议。如果没有其他显式协议,那么我们将强制启用tls 1.2,这是.NET目前唯一支持的安全协议。这段代码是向前兼容的,因为它将考虑将来不知道要添加的新协议类型,而且它还可以很好地处理.NET 4.7中的新
微软最近发布了有关这方面的最佳实践。https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
总结目标.NET Framework 4.7,删除设置SecurityProtocol的任何代码,这样操作系统将确保您使用最安全的解决方案。
注意:您还需要确保在操作系统上支持和启用最新版本的TLS。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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 |
有关更多信息和旧框架,请参阅MS链接。
为完整起见,下面是一个设置上述注册表项的PowerShell脚本:
1 2 | 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" |
这个问题的最佳解决方案似乎是升级到至少.NET 4.6或更高版本,它将自动选择强协议和强密码。
如果无法升级到.NET 4.6,则建议
system.net.servicePointManager.securityProtocol=securityProtocolType.tls11 securityProtocolType.tls12;
并使用注册表设置:
hkey_local_machinesoftwaremicrosoft.netframeworkv4.0.30319–schosestrongcrypto=1的双字hkey_local_machinesoftwarewow6432nodemicrosoft.netframeworkv4.0.30319–schosestrongcrypto=1的双字
结果使用的不是tls 1.0和强密码。
在我的测试中,尽管我的测试应用程序是为任何CPU构建的,但是只有wow6432节点中的设置有任何不同。
上述硬编码
1 2 | [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 |
对于密钥:hkey_local_machinesoftwaremicrosoft.netframeworkv4.0.30319值:schosestrongcrypto
必须将值设置为1。