.NET 4.5中的默认SecurityProtocol

问题描述 投票:215回答:14

与支持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协议。

更新:看看ServicePointManager中的.NET 4.0类,我看不到TLS 1.01.1的枚举值。在两个.NET 4.0/4.5中,默认值为SecurityProtocolType.Tls|SecurityProtocolType.Ssl3。希望这个默认值不会因在注册表中禁用SSLv3而中断。

但是,我已经决定将所有应用程序升级到.NET 4.5,并明确地将SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;添加到所有应用程序的所有引导代码中。

这将使各种apis和服务的出站请求不降级到SSLv3,并应选择最高级别的TLS

这种方法听起来合理还是矫枉过正?我有很多应用程序要更新,我希望将来证明它们,因为我听说即使TLS 1.0可能会在不久的将来被某些提供商弃用。

作为向API发出出站请求的客户端,在注册表中禁用SSL3是否会在.NET框架中产生影响?我默认看到,TLS 1.1和1.2没有启用,我们是否必须通过注册表启用它? RE http://support.microsoft.com/kb/245030

经过一些调查后,我相信注册表设置将不会有任何影响,因为它们适用于IIS(服务器子项)和浏览器(客户端子项)。

对不起,这篇文章变成了多个问题,接着是“可能”的答案。

.net security ssl
14个回答
227
投票

一些留下评论的人注意到将System.Net.ServicePointManager.SecurityProtocol设置为特定值意味着您的应用程序将无法利用将来可能成为.NET未来更新中的默认值的TLS版本。您可以改为打开或关闭您知道和关心的协议,而不是指定任何其他协议,而不是指定固定的协议列表。

要在不影响其他协议的情况下打开TLS 1.1和1.2:

System.Net.ServicePointManager.SecurityProtocol |= 
    SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

请注意使用|=打开这些标志而不关闭其他标志。

要在不影响其他协议的情况下关闭SSL3:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;

5
投票

微软最近发布了围绕此的最佳实践。 ServicePointManager.SecurityProtocol

Summary

目标.Net Framework 4.7,删除任何设置SecurityProtocol的代码,因此操作系统将确保您使用最安全的解决方案。

注意:您还需要确保在您的操作系统上支持和启用最新版本的TLS。

SystemDefault

有关更多信息和旧框架,请参阅MS链接。


3
投票

为了完整起见,这是一个Powershell脚本,用于设置上述注册表项:

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;
}

2
投票

如上所述,硬编码SystemDefault或显式SchUseStrongCrypto密钥的替代方法: 您可以告诉.NET使用SystemDefaultTlsVersions键的默认SCHANNEL设置, 例如。:

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

2
投票

解决此问题的最佳解决方案似乎是升级到至少.NET 4.6或更高版本,这将自动选择强协议以及强密码。

如果无法升级到.NET 4.6,请设置建议

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

并使用注册表设置:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = 1 HKORD_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319的DWORD - SchUseStrongCrypto = 1的DWORD

导致使用TLS 1.0以外的其他内容和强密码。

在我的测试中,只有Wow6432Node中的设置有所不同,即使我的测试应用程序是为任何CPU构建的。


-2
投票

对于密钥:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319值:SchUseStrongCrypto

您必须将值设置为1。


179
投票

.NET System.Net.ServicePointManager.SecurityProtocol中的默认4.0/4.5SecurityProtocolType.Tls|SecurityProtocolType.Ssl3

qazxsw poi支持qazxsw poi,而qazxsw poi支持.NET 4.0

但是,如果TLS 1.0安装在同一环境中,那么针对.NET 4.5的应用程序仍然可以支持高达TLS 1.2.NET 4.0安装在TLS 1.2之上,取代.NET 4.5

我通过使用.NET 4.5观察流量中的正确安全协议集并通过在.NET 4.0项目中手动设置枚举值来验证这一点:

System.dll

参考:

fiddler4

如果您在仅安装了.NET 4.0的环境中尝试攻击,您将获得异常:

未处理的异常:System.NotSupportedException:不支持请求的安全协议。在System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType v alue)

但是,我不推荐这种“黑客”,因为未来的补丁等可能会破坏它。*

因此,我决定取消对ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072; 的支持的最佳途径是:

  1. 将所有应用程序升级到namespace System.Net { [System.Flags] public enum SecurityProtocolType { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } }
  2. 将以下内容添加到引导代码中以覆盖默认和将来的证明: qazxsw poi

*有人纠正我,如果这个黑客是错误的,但初步测试我认为它有效


61
投票

您可以覆盖以下注册表中的默认行为:

.NET 4.0

SSLv3

有关详细信息,请参阅.NET 4.5


48
投票

使用System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;扩展名创建一个文本文件,其中包含以下内容:

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

双击安装......


18
投票

我发现,当我只指定TLS 1.2时,它仍会向下协商到1.1。 implementation of ServicePointManager

我已经在我的.net 4.5 web应用程序的Global.asax启动方法中指定了这个。


14
投票

经过斗争后,注册表更改机制对我有用。实际上我的应用程序运行为32位。所以我不得不改变路径下的值。

.reg

值类型需要为DWORD且值大于0。请使用1。


13
投票

当我的客户将TLS从1.0升级到1.2时,我遇到了问题。我的应用程序使用.net framework 3.5并在服务器上运行。所以我通过这种方式修复它:

  1. 修复程序

在调用HttpWebRequest.GetResponse()之前添加以下命令:

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

通过添加2个新类扩展2个DLL:System.Net和System.Security.Authentication

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg
  1. 更新Microsoft批处理

下载批次:

  • 对于Windows 2008 R2:windows6.1-kb3154518-x64.msu
  • 对于Windows 2012 R2:windows8.1-kb3154520-x64.msu

有关下载批次和更多详细信息,请参阅此处:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;


10
投票

以下代码将:

  • 打印启用的协议
  • 打印可用协议
  • 如果平台支持TLS1.2并且未启用它,则启用TLS1.2
  • 如果已启用,则禁用SSL3
  • 打印结果

常量:

  • 48是SSL3
  • 192是TLS1
  • 768是TLS1.1
  • 3072是TLS1.2

其他协议不会受到影响。这使得它与未来的协议(Tls1.3等)兼容。

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319

产量

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

7
投票

我在.NET 4.5.2下运行,我对这些答案都不满意。由于我正在与支持TLS 1.2的系统进行通信,并且看到SSL3,TLS 1.0和TLS 1.1都已损坏且使用不安全,我不想启用这些协议。在.NET 4.5.2下,SSL3和TLS 1.0协议都默认启用,我可以通过检查 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; } } 在代码中看到。在.NET 4.7下,有新的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协议模式,它明确地将协议选择交给操作系统,我认为依赖于注册表或其他系统配置设置是合适的。但是,.NET 4.5.2似乎并不支持这一点。为了编写与前向兼容的代码,即使在将来不可避免地破坏TLS 1.2,或者当我升级到.NET 4.7+并将更多责任交给操作系统选择合适的协议时,这仍将做出正确的决定。 ,我采用了以下代码:

// 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);

此代码将检测何时启用已知的不安全协议,在这种情况下,我们将删除这些不安全的协议。如果没有其他显式协议,我们将强制启用TLS 1.2,作为.NET此时唯一已知的安全协议。这段代码是向前兼容的,因为它将考虑将来不知道将要添加的新协议类型,并且它也将与.NET 4.7中的新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 状态一起使用,这意味着我不需要将来重新访问此代码。我强烈建议采用这样的方法,而不是无条件地对任何特定的安全协议状态进行硬编码,否则你将不得不重新编译并用新版本替换你的客户端,以便在TLS 1.2时升级到新的安全协议不可避免地会被破坏,或者更有可能您必须在服务器上保留现有的不安全协议多年,使您的组织成为攻击的目标。

© www.soinside.com 2019 - 2024. All rights reserved.