.NET 4.5 中的默认安全协议
Posted
技术标签:
【中文标题】.NET 4.5 中的默认安全协议【英文标题】:Default SecurityProtocol in .NET 4.5 【发布时间】:2015-04-01 21:24:06 【问题描述】:与支持TLS 1.2
的服务器通信的默认安全协议是什么?请问.NET
默认,选择服务器端支持的最高安全协议还是我要显式添加这行代码:
System.Net.ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
除了代码更改之外,还有其他方法可以更改此默认设置吗?
最后,.NET 4.0
是否只支持 TLS 1.0
?即我必须将客户端项目升级到 4.5 以支持TLS 1.2
。
我的动机是在客户端删除对SSLv3
的支持,即使服务器支持它(我已经有一个 powershell 脚本可以在机器注册表中禁用它)并支持服务器支持的最高 TLS 协议。
更新:
查看.NET 4.0
中的ServicePointManager
类,我看不到TLS 1.0
和1.1
的枚举值。在.NET 4.0/4.5
中,默认为SecurityProtocolType.Tls|SecurityProtocolType.Ssl3
。希望此默认设置不会因在注册表中禁用 SSLv3
而中断。
但是,我决定必须将所有应用程序升级到 .NET 4.5
,并在所有应用程序的所有引导代码中显式添加 SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
。
这将使对各种api和服务的出站请求不会降级到SSLv3
,并且应该选择TLS
的***别。
这种方法听起来合理还是矫枉过正?我有许多应用程序要更新,我想在未来对它们进行验证,因为我听说在不久的将来某些提供商可能会弃用 TLS 1.0
。
作为向 API 发出出站请求的客户端,在注册表中禁用 SSL3 是否会对 .NET 框架产生影响?我看到默认情况下,TLS 1.1 和 1.2 未启用,我们是否必须通过注册表启用它?回复http://support.microsoft.com/kb/245030。
经过一番调查,我相信注册表设置不会有任何影响,因为它们适用于 IIS(服务器子项)和浏览器(客户端子项)。
抱歉,这篇帖子变成了多个问题,随后给出了“可能”的答案。
【问题讨论】:
仅供参考:有关 TLS 的最新最佳实践:docs.microsoft.com/en-us/dotnet/framework/network-programming/… 对于那些想看到这个问题的最佳答案的人,按投票排序! 相关 SO 问答:***.com/questions/41618766/… 读者应该注意这个问题已经过时了,新的建议自 2020 年起已经到位。 【参考方案1】:创建一个带有.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://gist.githubusercontent.com/dana-n/174759ce95e04fa1a8fd691f633ccbd3/raw/NET40-Enable-TLS-1_2.reg
双击安装...
【讨论】:
您提供的链接似乎存在 SSL 证书问题。 即使我添加了这些注册表项,我仍然有这个问题。有什么想法吗? @Samidjo - 您使用的是什么 .NET 版本?卢克的回答比我的要详细得多,但看起来您至少需要安装 .NET 4.5。此外,如果您刚刚进行了更改,您可能需要回收应用程序池。这些都是猜测,所以如果没有更多细节,我可能会提供更多帮助:) 最近对服务器应用的补丁support.microsoft.com/en-us/help/4019114/… 导致我们的 .net 4.5.2 应用程序在 https REST 请求上失败。这些键解决了我们的问题。【参考方案2】:在其他答案中留下 cmets 的一些人指出,将 System.Net.ServicePointManager.SecurityProtocol
设置为特定值意味着您的应用将无法利用未来可能成为 .NET 更新中默认值的 TLS 版本.不要指定固定的协议列表,而是执行以下操作:
对于 .NET 4.7 或更高版本,请勿设置 System.Net.ServicePointManager.SecurityProtocol
。默认值 (SecurityProtocolType.SystemDefault
) 将允许操作系统使用它知道和配置的任何版本,包括在创建应用程序时可能不存在的任何新版本。
对于早期版本的 .NET Framework,您可以改为打开或关闭您知道和关心的协议,而让其他协议保持原样。
在不影响其他协议的情况下开启 TLS 1.1 和 1.2:
System.Net.ServicePointManager.SecurityProtocol |=
SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
注意使用|=
打开这些标志而不关闭其他标志。
关闭 SSL3 而不影响其他协议:
System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
【讨论】:
这才是真正的正确答案。接受的答案将确保您的应用始终关闭新的 TLS 版本,除非您返回并更新您的代码。 @Gertsen 不,这是按位或,所以如果它们关闭,它只会打开相应的位。如果这些位已经打开,则不会发生任何变化。 与此等效的 PowerShell 是[Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12)
Invoke-RestMethod 依赖于相同的底层 .NET 框架库。
由于没有人谈论将这段代码放在哪里,我成功地将它放入我的 ASP.NET MVC 应用程序的 Global.asax.cs 的 Application_Start 中。我正在寻找如何让我的 SMTP 请求通过 TLS1.2 而不是通过 TLS1.0 发送。我还添加了 &= ~SecurityProtocolType.Tls 来关闭 TLS 1.0
在 VB 中相当于Net.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
【参考方案3】:
有两种可能的情况,
如果您的应用程序在 .net 框架 4.5 或更低版本上运行,并且您可以轻松地将新代码部署到生产环境中,那么您可以使用以下解决方案。
您可以在调用 api 之前添加以下代码行,
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5
如果您无法部署新代码并且您想使用生产中存在的相同代码进行解析,那么您有两种选择。
选项 1:
[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
然后创建一个扩展名为 .reg 的文件并安装。
注意:此设置将应用于注册表级别,并适用于该计算机上存在的所有应用程序,如果您想限制为仅单个应用程序,则可以使用Option 2
选项 2 :这可以通过更改配置文件中的一些配置设置来完成。 您可以在配置文件中添加其中任何一个。
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
</runtime>
或
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"
</runtime>
【讨论】:
【参考方案4】:如果您可以使用 .NET 4.7.1 或更高版本,它将使用 TLS 1.2 作为基于操作系统功能的最低协议。 根据 Microsoft 的建议:
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.
【讨论】:
【参考方案5】:根据Transport Layer Security (TLS) best practices with the .NET Framework:
为确保 .NET Framework 应用程序保持安全,TLS 版本不应被硬编码。 而是设置注册表项:SystemDefaultTlsVersions
和 @987654323 @:
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
【讨论】:
【参考方案6】:以下代码将:
支持打印的协议 打印可用协议 如果平台支持 TLS1.2 并且开始时未启用,则启用 TLS1.2 如果启用 SSL3,则禁用它 打印最终结果常量:
48 是 SSL3 192 是 TLS1 768 是 TLS1.1 3072 是 TLS1.2其他协议不会受到影响。这使得它与未来的协议(Tls1.3 等)兼容。
代码
// 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);
输出
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
【讨论】:
【参考方案7】:Microsoft 最近发布了与此相关的最佳实践。 https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
总结
针对 .Net Framework 4.7,删除任何设置 SecurityProtocol 的代码,操作系统将确保您使用最安全的解决方案。
注意:您还需要确保您的操作系统支持并启用最新版本的 TLS。
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 链接。
【讨论】:
问题是 tls 1.1 和 tls 1.2 将无法在 Windows 7 和 Server 2008 上运行,如果您遵循指南(保持 SecurityProtocolType.SystemDefault),因为它们在这些操作系统无需更改注册表。这使得 SystemDefault 在实践中被设计破坏了。微软真的把这个搞砸了。 很好,谢谢@osexpert,很好。我已经修改了答案以包含有关受支持操作系统的信息,因此对于运行仅针对 4.7 还不够的旧操作系统的人来说,这不足为奇。 注意:还有一个 KB 用于在某些操作系统上启用较新的协议:support.microsoft.com/en-my/help/3140245/… 如果注册表设置不是一个选项,我认为这是 .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;
【参考方案8】:
您可以覆盖以下注册表中的默认行为:
Key : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1
和
Key : HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319
Value: SchUseStrongCrypto
Type: REG_DWORD
Data : 1
详情请见implementation of ServicePointManager
。
【讨论】:
谢谢,我不知道这个。我会测试它。我创建了一个 powershel 脚本来设置它:gist.github.com/lukehutton/ab80d207172a923401b1 更改注册表看起来不是一个好的解决方案。如果应用程序想要支持 TLS1,那么应用程序应该考虑它。不是运行环境。否则,它可能会损害其他应用程序或使部署和升级您的应用程序陷入困境。 @MikhailG 恰恰相反。注册表更改是首选方法。 SChannel 提供了底层协商的抽象,您希望您的应用程序使用最高支持的安全级别。当新协议发布并且您的软件无法使用它们时,在软件中人为地限制它会导致未来出现问题。如果在软件中可以选择说只使用比给定协议更好的选择,那就太好了,但是如果不阻止未来版本的工作,就没有选择。不过确实禁用了 SSL v3。 命令行:reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64
(和/或/reg:32
)
@MikhailG:设置注册表不会阻止应用程序支持旧协议。它只会更改默认值(目前包括 tls 1.0)。此外,.Net 4.6+ 中的默认行为是使用强加密;在这种情况下,此注册表项仅可用作禁用强加密的一种手段。【参考方案9】:
经过一番挣扎,注册表更改机制对我有用。实际上我的应用程序运行为 32 位。所以我不得不改变路径下的值。
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319
值类型需要为DWORD且值大于0。最好使用1.
【讨论】:
不准确。对于 .NET 4.5.2,这需要设置为 1(或更高);但对于 .NET 4.6,不设置为 0 就足够了(即可以取消设置)。 哦,我没有在 .Net 4.6 中测试。我的发现在博文joymonscode.blogspot.com/2015/08/… 您提到的注册表项应为“Wow6432Node”。由于某种原因,您省略了“节点”部分。我试图编辑您的回复,但我的更改只有 4 个字母,所以它不会让我这样做。 :\ 我不得不退回 IIS 以使此设置作为默认设置自行激活。【参考方案10】:我在 .NET 4.5.2 下运行,我对这些答案都不满意。当我与支持 TLS 1.2 的系统交谈时,看到 SSL3、TLS 1.0 和 TLS 1.1 都已损坏且使用不安全,我不想启用这些协议。在 .NET 4.5.2 下,SSL3 和 TLS 1.0 协议都默认启用,我可以通过检查 ServicePointManager.SecurityProtocol
在代码中看到。在 .NET 4.7 下,有新的SystemDefault
协议模式,它明确地将协议的选择移交给操作系统,我认为依赖注册表或其他系统配置设置是合适的。然而,.NET 4.5.2 似乎不支持这一点。为了编写向前兼容的代码,即使将来 TLS 1.2 不可避免地被破坏,或者当我升级到 .NET 4.7+ 并将选择适当协议的更多责任移交给操作系统时,这也将继续做出正确的决定,我采用了以下代码:
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 中的新 SystemDefault
状态很好地配合,这意味着我不会将来必须重新访问此代码。我强烈建议采用这样的方法,而不是无条件地对任何特定的安全协议状态进行硬编码,否则您必须重新编译并用新版本替换客户端才能在 TLS 1.2 时升级到新的安全协议不可避免地被破坏,或者您更有可能不得不在您的服务器上启用现有的不安全协议多年,从而使您的组织成为攻击的目标。
【讨论】:
这个答案似乎是最深思熟虑的,但是,除非我遗漏了什么,否则我不确定它是否会在 TLS 1.2 不可避免地中断时向前兼容。从我在 .NET 4.7.2 应用程序中看到的情况来看,SecurityProtocolType.SystemDefault
标志的计算结果为 0
,因此使用 TLS 1.2 的按位包含或标志检查 if (securityProtocols == 0)
将始终包含 TLS 1.2,即使它是“休息”,对吧?这里没有锐利的拍摄。我真的在努力寻找最好的前进道路。
我已修改您的代码以包含此代码,它似乎可以工作并且向前兼容:if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) securityProtocols |= SecurityProtocolType.Tls12;
。
@Griswald_911,我在我的 4.7.2 控制台应用程序中有类似的代码,我发现这一行 securityProtocols |= SecurityProtocolType.Tls12;
(没有 if 块)不维护 SystemDefault,securityProtocols 之后只有 TLS2。那么您的意思是当值为 SystemDefault 时,不应更新任何值?关于前向兼容,您是否假设操作系统会负责启用更新的协议,如 TLS 1.3?
@Yang -- 正确。 securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the
SecurityProtocolType` 枚举行有一个[Flags]
属性,SystemDefault 枚举值为0
,SystemDefault 值将被剥离,即使它之前已设置。最终结果是您可以将SevicePointManager.SecurityProtocol
设置为0,或设置为其他枚举值的任意组合。如果您将其设置为 SystemDefault,则基本上您选择退出自己指定协议并让操作系统决定。
@Yang -- 关键是,在将值设置为 SystemDefault 之后,您的应用程序应该使用操作系统指定的任何内容——在最新版本的 Windows 10 中是 TLS 1.2。想法是,将来当 TLS 1.3 成为标准时,您不必修改应用程序即可继承该功能。请参阅文档here,其中 SystemDefault “允许操作系统选择要使用的最佳协议,并阻止不安全的协议”。【参考方案11】:
此问题的最佳解决方案似乎是至少升级到 .NET 4.6 或更高版本,它将自动选择强协议和强密码。
如果不能升级到.NET 4.6,建议设置
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 |安全协议类型.Tls12;
并使用注册表设置:
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 和强密码以外的其他内容。
在我的测试中,只有 Wow6432Node 中的设置有所不同,即使我的测试应用程序是为任何 CPU 构建的。
【讨论】:
澄清:您只需要设置 SevicePointManager.SecurityProtocol 或设置注册表设置。没有必要两者都做。对于我的应用程序,我选择只设置 ServicePointManager.SecurityProtocol。我的理由是设置注册表会影响整个机器,我不希望其他人的应用程序中断,因为它依赖于 TLS 1.0。【参考方案12】:当我的客户将 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;
-
更新 Microsoft 批处理
批量下载:
对于 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-and-server-2008-r2-sp1
【讨论】:
是否可以在不更改源代码的情况下更改 SecurityProtocol ?比如 machine.config 或 app.config。 哇。那是年度巫术奖……东西……就在那里。你摇滚郊区!【参考方案13】:硬编码 ServicePointManager.SecurityProtocol
或上面提到的显式 SchUseStrongCrypto 密钥的替代方法:
您可以通过 SystemDefaultTlsVersions 键告诉 .NET 使用默认 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
【讨论】:
【参考方案14】:为了完整起见,这里是一个设置上述注册表项的 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"
【讨论】:
【参考方案15】:我发现当我只指定 TLS 1.2 时,它仍然会向下协商到 1.1。
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
我已在我的 .net 4.5 Web 应用程序的 Global.asax 启动方法中指定了这一点。
【讨论】:
服务器上支持的安全协议是什么?我相信这也是这里的因素,可能 1.1 是服务器上的最新版本。 www.passionatecoder.ca 赞成,因为这是唯一一个说明在哪里放置作为解决方案的代码行的答案。 客户端(例如您的 C# WebClient)和服务器(您正在调用的 API 服务器)将协商使用两者都支持的最高协议。因此,如果您的客户端支持 TLS 1.2,但服务器仅支持 TLS 1.1 - 客户端将使用 TLS 1.1(除非您从客户端删除 TLS 1.1 - 在这种情况下,他们可能找不到相互支持的协议,并且客户端会出错)跨度> 必须在 global.asax.cs 中使用 System.Net 添加【参考方案16】:对于密钥:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319 值:SchUseStrongCrypto
您必须将值设置为 1。
【讨论】:
我认为你被否决了,因为它与@Jira Mares 提供的答案相同,但细节较少【参考方案17】:.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
之上,替换 System.dll
。
我已通过使用fiddler4
观察流量中设置的正确安全协议并在.NET 4.0
项目中手动设置枚举值来验证这一点:
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
的环境中尝试破解,您将收到异常:
未处理的异常:System.NotSupportedException:请求的安全协议不受支持。 在 System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType v 值)
但是,我不推荐这种“破解”,因为未来的补丁等可能会破坏它。*
因此,我决定删除对SSLv3
的支持的最佳途径是:
-
将所有应用程序升级到
.NET 4.5
将以下内容添加到 boostrapping 代码中以覆盖默认值和未来证明:
System.Net.ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
*如果这个 hack 是错误的,请有人纠正我,但初步测试我认为它有效
【讨论】:
请参阅imperialviolet.org/2014/12/08/poodleagain.html “这似乎是重申低于 TLS 1.2 且带有 AEAD 密码套件的所有内容都已被密码破解的好时机。” @Mathew,通过查看ServicePointManager.cs
的源代码参见referencesource.microsoft.com/#System/net/System/Net/…
我一直看到人们声称 .NET 4.5
默认为 Tls12 - 但正如您在这里所说的那样,它没有。它使您可以选择将其用于SecurityProtocol
我不会否决这个答案,因为它确实提供了很多有用的信息,但实施硬编码协议版本并不是一个好主意,因为它会限制应用程序使用最佳可用加密并可能导致在未来的安全问题上。更改注册表以更改 .Net 的默认行为以实际支持现代协议是非常可取的。 (但值得注意的是,注册表更改也会禁用 SSL v3。)
在 FW 4.6 和 4.7 上,现在的默认值为 SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12
support.microsoft.com/en-us/help/3069494/…以上是关于.NET 4.5 中的默认安全协议的主要内容,如果未能解决你的问题,请参考以下文章