.Net Framework 4.6.1未默认使用TLS 1.2

60

我们的客户最近将安全协议升级到TLS 1.2。因此,我们将我们的应用程序升级到4.6.1版本,期望安全协议将默认为TLS 1.2,但实际上并没有。有任何想法是为什么?


你怎么知道它不是?你尝试了什么? - Panagiotis Kanavos
TLS 1.2在4.6.2中默认工作 - 使用HttpClient检索Google.com首页(TLS1.2)没有问题。 - Panagiotis Kanavos
1
当连接服务器时,我们遇到了这个错误:“这可能是由于在HTTPS情况下,服务器证书未正确配置HTTP.SYS引起的。”但是,在Global.asax文件的启动方法中添加以下行可以解决此问题。ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;但是,我们想知道为什么我们需要设置这个,如果我们的应用程序在.Net 4.6.1中。 - Harihara Iyer
什么错误?什么代码?我无法在针对4.6.1的控制台应用程序中重现任何内容。如果证书有误,您将在任何客户端(包括浏览器)中都会收到错误提示。 - Panagiotis Kanavos
在 Windows 10 上,使用针对 4.6.1 的控制台应用程序调用仅接受 TLS1.2 的 Web 页面时,没有重现问题。实际上,如果我强制使用 TLS1.1,则会出现“请求被中止:无法创建 SSL/TLS 安全通道。”的错误。 - Panagiotis Kanavos
显示剩余2条评论
11个回答

57

我曾经遇到过类似的问题,以下是解决方法:

  1. 打开PowerShell并使用命令 [Net.ServicePointManager]::SecurityProtocol 检查支持的协议。

  2. 运行以下两个 cmdlet 来设置.NET Framework 强密码学注册表键

    在64位 .Net Framework 上启用强密码学(版本 4 及以上)

    Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord

    在32位 .Net Framework 上启用强密码学(版本 4 及以上)

    Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord

  3. 重启 PowerShell 并再次使用命令 [Net.ServicePointManager]::SecurityProtocol 检查支持的协议。

现在它应该显示 Tls12

希望这能帮到你。


2
对我有帮助 - 谢谢!顺便说一句,如果有时间,请为其他人在Microsoft和.NetFramework之间添加反斜杠: "Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord"。这两个命令也是相同的。可能需要注意这一点。再次感谢。 - sean2078
1
感谢您的评论。64位版本还应包括Wow6432node键。将进行修复。 - user24601
这个方法也解决了我的问题。我是通过PowerShell调用C# DLL cmdlet,这是我唯一能让它工作的方法。浪费了好几个小时。 - Omzig
在已安装TLS 1.2热修补程序的Windows Server 2008上,该命令无法正常工作。命令行仍然返回“Ssl3, Tls”。 - xr280xr
3
请注意,对于已安装.NET 4.7.2的我的情况,执行这两个命令前后,SecurityProtocol 返回值都是 SystemDefault。然而,这仍然可以正常工作! - RichardM
显示剩余6条评论

28

正如其他人所提到的,为了在现有的.NET应用程序中启用TLS 1.2而不需要在应用程序代码中显式设置协议版本,必须设置一些Windows注册表键。

为了使.NET 4.x代码默认选择最强的可用协议(即在代码中未明确指定协议时),需要以下注册表键:(详情请见此处)

在32位和64位版本的Windows上HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto: 0X00000001

在64位版本的Windows上HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto: 0X00000001

当在64位系统上运行32位应用程序时,需要 WOW6432Node 值来启用TLS 1.2。

但是这里有一个快速简单的解决方案:https://github.com/TheLevelUp/pos-tls-patcher

更新:

如果您的目标是.NET 4.6或4.7,您会对.NET Framework中的传输层安全性(TLS)最佳做法感兴趣。

请注意,上面链接的TLS Patcher非常遵循微软针对现有无法定位到.NET 4.6或更高版本的.NET 4.0和4.5应用程序的建议。

6
我认为这应该是被接受的答案。我们遇到了相同的问题,并观察到以下情况:正常的.Net EXE表现正常。如果程序集托管在本地进程中(例如IIS,Office插件),只有在进行了注册表设置后才会使用TLS 1.2。 - Stefan Egli
@StefanEgli 我能理解你的痛苦。不确定为什么这些信息没有更好地记录下来。我们正在努力宣传:http://blog.thelevelup.com/pci-security-is-your-restaurant-ready/ - user24601
@StefanEgli 如果你想要在本地代码中使用TLS 1.2,你还需要设置Schannel注册表键:https://learn.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 - user24601
1
密钥中的 \4.0.30319 部分不正确,应为 \v4.0.30319。 - Jake

25
安全协议没有默认使用TLS 1.2的原因是因为.NET Framework 4.6.1中没有此项的默认值。如果这是重复已经说过的内容,我很抱歉,但我想要详细阐述一下,由于声望不足,我无法发表评论。
4.6.2中也没有默认值,但是像上面某位评论者所提到的,控制台应用程序似乎默认使用TLS 1.2。我在一个针对4.6.2的网站项目中尝试了完全相同的代码,但它并没有默认使用TLS 1.2。
4.7及以上版本具有SecurityProtocolType.SystemDefault的默认值。
“这允许基于SslStream的.NET Framework网络API(例如FTP、HTTP和SMTP)从操作系统或系统管理员执行的任何自定义配置中继承默认安全协议” https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol?view=netframework-4.7#System_Net_ServicePointManager_SecurityProtocol

10

不错的发现!这也为我们解决了问题,因为我们之前没有设置它。 - Philmatic

7

基于以下链接

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

我已经添加了

AppContext.SetSwitch("Switch.System.Net.DontEnableSystemDefaultTlsVersions", false);

我将此代码添加到我的代码中,这为我解决了问题。这应该默认为操作系统支持的最高级别,这与4.7及以上版本的默认行为相同。


7
该属性为ServicePointManager.SecurityProtocol,用于选择仅使用安全超文本传输协议(HTTPS)方案的新连接所使用的安全套接字层(SSL)或传输层安全性(TLS)协议的版本;现有连接不会更改。请注意,此属性没有列出默认值,是有意的。 安全环境不断变化,为避免已知弱点,随着时间的推移,将更改默认协议和保护级别。默认值将因个人计算机配置、安装的软件以及应用的补丁而异。 该段来源:此处

.NET 4.6.1的默认安全协议不是TLS 1.2 - 您必须将ServicePointManager.SecurityProtocol的值设置为它以添加支持。 - Camille G.
这个回答如何解决问题?楼主说TLS1.2没有起作用,但实际上应该是可以的。 - Panagiotis Kanavos
2
答案并不重要。如果附带参考资料,评论可能会有用。在4.6.2中,默认启用TLS1.2。 - Panagiotis Kanavos
是的 - 你怎么知道4.6.1默认不启用TLS1.2?答案并没有说那个。相反,它说4.6+将默认使用更强的算法。 - Panagiotis Kanavos
2
@PanagiotisKanavos 我更新了引用的MSDN段落。 - Camille G.
显示剩余3条评论

5
我也遇到了这个问题。当本地应用程序尝试连接支持TLS 1.1和TLS 1.2的服务器时,它以前会收到“远程主机强制关闭现有连接”异常,或者当没有正确启用TLS 1.1/1.2时,它以前会收到“Win32Exception:客户端和服务器无法通信,因为它们不具备公共算法”。
以下是在x64 Windows操作系统中需要的所有注册表键和值。如果您有32位操作系统(x86),只需删除最后两行。该注册表脚本将禁用TLS 1.0。需要重新启动操作系统。
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ssl 3.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ssl 3.0\client]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ssl 3.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.0\client]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.1]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.1\client]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.1\server]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.2]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.2\client]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.2\server]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[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

1

我在初始页面的代码中使用了这个。该应用程序是使用VB.NET的Web表单,使用.NET Framework 4.6.1。

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

2
这实际上覆盖了所有其他版本,更不用说它没有回答问题了。 - kuskmen
2
请勿在应用程序代码中硬编码安全协议。您希望遵循上面答案中的建议,这也符合微软TLS最佳实践与.NET的要求。 - user24601
奇怪。我有一个基于Framework 3.5的代码库,它从网站和.exe文件中共享了一个dll。这个dll、网站和.exe都升级到了Framework 4.6.2。.exe文件工作正常,并使用TLS 1.2。但是网站没有。我不得不根据这篇文章明确指定协议版本才能让网站正常工作。 - Matthew Allen

1
我采取以下步骤使用最新的安全协议TLS v.1.2:
在注册表中禁用旧协议SSL2.0、SSL3.0、TLS1.0、TLS1.1,启用TLS1.2,并启用.NET Framework的强密码学。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000001
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接