.NET 4.5中的默认SecurityProtocol
与支持TLS 1.2
服务器进行通信的默认安全协议是什么? .NET
默认情况下,select服务器端支持的最高安全协议,或者我必须显式添加下面这行代码:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
有没有办法改变这个默认值,除了代码更改?
最后, .NET 4.0
只支持TLS 1.0
吗? 即我必须将客户端项目升级到4.5来支持TLS 1.2
。
我的动机是在客户端移除对SSLv3
支持,即使服务器支持它(我已经有一个PowerShell脚本来在机器registry中禁用它),并且支持服务器支持的最高TLS协议。
更新:看看.NET 4.0
中的ServicePointManager
类,我看不到TLS 1.0
和1.1
枚举值。 在.NET 4.0/4.5
,默认值是SecurityProtocolType.Tls|SecurityProtocolType.Ssl3
。 希望这个默认值不会因在registry中禁用SSLv3
而中断。
不过,我决定必须将所有应用升级到.NET 4.5
并明确添加SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
反正所有应用程序的所有引导代码。
这将使不同的apis和服务的出站请求不降级到SSLv3
并应select最高级别的TLS
。
这种方法是合理的还是过度的? 我有很多应用程序需要更新,而且我希望将来能够certificate这些应用程序,因为我听说即使TLS 1.0
可能会在不久的将来被某些提供商弃用。
作为向API发出出站请求的客户端,在registry中禁用SSL3甚至会在.NET框架中产生影响? 我看到默认情况下,TLS 1.1和1.2没有启用,我们必须通过registry启用它? RE http://support.microsoft.com/kb/245030 。
经过一番调查,我相信registry设置将不会有任何影响,因为它们适用于IIS(服务器子键)和浏览器(客户端子键)。
对不起,这篇文章变成了多个问题,后面跟着“也许”的答案。
.NET 4.0/4.5
的默认System.Net.ServicePointManager.SecurityProtocol
是SecurityProtocolType.Tls|SecurityProtocolType.Ssl3
。
.NET 4.0
支持TLS 1.0
而.NET 4.5
支持TLS 1.2
但是,如果.NET 4.5
安装在相同的环境中,则以.NET 4.0
为目标的应用程序仍然可以支持TLS 1.2
。 .NET 4.5
安装在.NET 4.0
之上,replaceSystem.dll
。
我已经通过观察使用fiddler4
在stream量中设置的正确安全协议并通过在.NET 4.0
项目中手动设置枚举值来validation了这一点:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
参考:
namespace System.Net { [System.Flags] public enum SecurityProtocolType { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } }
如果您尝试在安装了.NET 4.0
的环境中进行攻击,您将得到以下exception:
未处理的exception:System.NotSupportedException:不支持请求的安全协议。 在System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType值)
不过,我不会推荐这个“黑客”,因为未来的补丁等可能会破坏它。
因此,我决定取消对SSLv3
支持的最佳途径是:
- 将所有应用程序升级到
.NET 4.5
-
添加以下代码来重写代码以覆盖默认和将来的certificate:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
*有人纠正我,如果这个黑客是错误的,但最初的testing,我看到它的作品
其中一些留下评论注意到,将System.Net.ServicePointManager.SecurityProtocol
设置为特定的值意味着您的应用程序将无法利用未来的TLS版本,这些版本可能成为未来.NET更新中的默认值。 而不是指定一个固定的协议列表,而是可以打开或closures你知道和关心的协议,让其他人保持原样。
打开TLS 1.1和1.2而不影响其他协议:
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
注意使用|=
打开这些标志而不closures其他标志。
要closuresSSL3而不影响其他协议:
System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
您可以覆盖以下registry中的默认行为:
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 Value: SchUseStrongCrypto
有关详细信息,请参阅ServicePointManager的实现: http : //referencesource.microsoft.com/#System/net/System/Net/ServicePointManager.cs.html%2cbcb6e5c0502bfce6%2cretions
创build一个扩展名为.reg
的文本文件,内容如下:
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
双击安装…
经过一番斗争后,注册机构的变更机制为我工作。 其实我的应用程序运行为32位。 所以我不得不改变path下的价值。
HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319
值types需要为DWORD且值大于0。
当我的客户将TLS从1.0升级到1.2时,我遇到了问题。 我的应用程序使用.net framework 3.5并在服务器上运行。 所以我通过这种方式来修复它:
- 修复程序
在调用HttpWebRequest.GetResponse()之前添加这个命令:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;
通过添加2个新的类扩展2个DLL:System.Net和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; } }
- 更新微软批处理
下载批次:
- 对于Windows 2008 R2:windows6.1-kb3154518-x64.msu
- 对于Windows 2012 R2: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和服务器-2008-R2-SP1
我发现当我只指定TLS 1.2时,它仍然会协商到1.1。 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
我已经在我的.net 4.5 web应用程序的Global.asax启动方法中指定了这一点。
为了完整起见,下面是一个设置上述registry项的Powershell脚本:
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"
这个问题的最佳解决scheme似乎是升级到至less.NET 4.6或更高版本,这将自动select强协议以及强密码。
如果你不能升级到.NET 4.6,那么设置的build议
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
并使用registry设置:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 – SchUseStrongCrypto = DWORD of 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 – SchUseStrongCrypto = DWORD of 1
结果使用TLS 1.0以外的内容和强密码。
在我的testing中,只有Wow6432Node中的设置有所不同,即使我的testing应用程序是为任何CPU构build的。
如上所述,对ServicePointManager.SecurityProtocol
或显式的SchUseStrongCrypto键进行硬编码的替代方法:
您可以告诉.NET使用SystemDefaultTlsVersions项的默认SCHANNEL设置,
例如:
[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
For Key:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Value:SchUseStrongCrypto
您必须将该值设置为1。