.Net Framework 4.6.1 不默认为 TLS 1.2

Posted

技术标签:

【中文标题】.Net Framework 4.6.1 不默认为 TLS 1.2【英文标题】:.Net Framework 4.6.1 not defaulting to TLS 1.2 【发布时间】:2017-10-07 22:15:40 【问题描述】:

我们的客户最近将安全协议升级到 TLS 1.2。因此,我们将应用程序升级到 4.6.1,期望安全协议默认为 TLS 1.2,但事实并非如此。知道为什么吗?

【问题讨论】:

你怎么知道不是?你尝试了什么? TLS 1.2 默认在 4.6.2 中工作 - 使用 HttpClient 检索 Google.com 主页 (TLS1.2) 没有问题 我们在连接到服务器时收到此错误“这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书。”但是,在 Global.asax 文件的启动方法中添加此行时,修复了此问题。 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Tls11 |安全协议类型.Tls12 |安全协议类型.Ssl3;但是我们想知道如果我们的应用程序在 .Net 4.6.1 中,为什么需要设置它 什么错误?什么代码?我无法使用针对 4.6.1 的控制台应用程序重现任何内容。如果 certificate 错误,您将在 any 客户端(包括浏览器)中遇到错误。 没有在 Windows 10 上针对 4.6.1 的控制台应用程序进行复制,调用仅接受带有 HttpClient 的 TLS1.2 的网页。事实上,如果我强制 TLS1.1,我会得到The request was aborted: Could not create SSL/TLS secure channel. 【参考方案1】:

我遇到了类似的问题,这对我有用。

    打开Powershell并使用[Net.ServicePointManager]::SecurityProtocol检查支持的协议

    运行以下 2 个 cmdlet 来设置.NET Framework strong cryptography registry keys:

    在 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

    重新启动 Powershell 并使用 [Net.ServicePointManager]::SecurityProtocol 再次检查支持的协议

它现在也应该显示Tls12

希望对你有帮助

【讨论】:

这肯定适用于安装了 .NET 4.6+ 的 .NET 4.x 应用程序代码。 为我工作 - 谢谢!顺便说一句,如果有时间,请在 Microsoft 和 .NetFramework 之间为其他人添加反斜杠:“Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord" .. 两个命令也一样。或许可以对此做个说明。再次感谢。 感谢 cmets。 64 位还应包括 Wow6432node 密钥。会修复的。 我的最后两次编辑没有被接受,但是您可以在下面的my answer 中看到正确的注册表项值。 请注意,对于我来说,安装了 .NET 4.7.2 后,SecurityProtocol 在执行这两个命令之前和之后都返回了SystemDefault。但是,这仍然有效!【参考方案2】:

正如其他人所提到的,必须设置许多 Windows 注册表项才能在现有 .NET 应用程序中启用 TLS 1.2,而无需在应用程序代码中明确设置协议版本。

为了使.NET 4.x code select the strongest available protocol 默认情况下(即当协议未在代码中明确指定时),需要以下注册表项:

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

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

WOW6432Node 值是在 64 位系统上运行时在 32 位应用程序中启用 TLS 1.2 所必需的。

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

更新:

如果您的目标是 .NET 4.6 或 4.7,您会对 Transport Layer Security (TLS) best practices with the .NET Framework 感兴趣。

请注意,上面链接的 TLS Patcher 非常遵循 Microsoft 对无法以 .NET 4.6 或更高版本为目标的现有 .NET 4.0 和 4.5 应用程序的建议。

【讨论】:

我认为这应该是公认的答案。我们遇到了同样的问题并观察到以下情况: 正常的 .Net EXE 可以按预期工作。如果进行了注册表设置,则托管在本机进程(例如 IIS、Office 插件)中的程序集仅使用 TLS 1.2。 @StefanEgli 我能感觉到你的痛苦。不知道为什么没有更好地记录此信息。我们正在努力宣传:blog.thelevelup.com/pci-security-is-your-restaurant-ready @StefanEgli 如果您希望在本机代码中使用 TLS 1.2,您还需要设置 Schannel 注册表项:docs.microsoft.com/en-us/windows-server/security/tls/… 密钥的\4.0.30319部分不正确,应该是\v4.0.30319【参考方案3】:

安全协议没有默认使用 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://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol?view=netframework-4.7#System_Net_ServicePointManager_SecurityProtocol

【讨论】:

【参考方案4】:

我们在 IIS 中托管 .NET 4.6.2 应用程序时遇到了类似的问题。

我们可以通过在 web.config 中添加 httpRuntime 元素来解决这个问题。没有它,我们的服务不会默认使用 TLS 1.2。

<httpRuntime targetFramework="4.6.2" />

欲了解更多信息,请参阅https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.httpruntimesection?view=netframework-4.7.2

【讨论】:

不错的发现!这也为我们解决了这个问题,因为我们没有设置它。【参考方案5】:

MSDN:ServicePointManager.SecurityProtocol 属性

此属性选择安全套接字层 (SSL) 的版本或 用于新连接的传输层安全 (TLS) 协议 仅使用安全超文本传输​​协议 (HTTPS) 方案; 现有的连接不会改变。 请注意,没有默认值 故意为该属性列出。

安全形势不断变化,默认协议和 保护级别随着时间的推移而改变,以避免已知 弱点。默认值会因个别机器而异 配置,以及安装在哪个软件上,以及安装在哪个软件上 已应用补丁。

取自here

【讨论】:

.NET 4.6.1 的默认安全协议不是 TLS 1.2 - 您必须为其设置 ServicePointManager.SecurityProtocol 的值以添加支持 这如何回答这个问题? OP 说 TLS1.2 在应该的时候不起作用 我将这个问题理解为“我什么都没做,但预期 TLS 1.2 有效” 答案 不相关。如果附有参考,评论可能会出现。在 4.6.2 中默认启用 TLS1.2 @PanagiotisKanavos 我更新了引用的 MSDN 段落【参考方案6】:

基于以下链接

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

我已经添加了

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

我的代码,这解决了我的问题。这意味着默认为操作系统支持的***别,这与您在 4.7 及更高版本中默认获得的行为相同。

【讨论】:

【参考方案7】:

我也遇到了这个问题。当本地应用程序尝试连接到支持 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

【讨论】:

【参考方案8】:

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

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

【讨论】:

这实际上覆盖了所有其他版本,更不用说它没有回答问题。 请不要在应用程序代码中硬编码安全协议。您希望遵循上述答案中的建议,这些建议也符合 Microsoft TLS Best Practices with .NET 奇数。我有一个从 Framework 3.5 开始的代码库,它从网站和 .exe 共享一个 dll。 dll、网站和.exe都升级到了Framework 4.6.2。 .exe 运行良好并使用了 TLS 1.2。该网站没有。我必须根据这篇文章明确指定协议版本才能使网站正常运行。【参考方案9】:

我执行了以下步骤来使用最新的安全协议 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

【讨论】:

【参考方案10】:

我在我的 api 中尝试了以下代码,但它不适用于 Kaltura 帐户集成(bec'z Kaltura API 升级到 TLS 1.2),它开始工作。 .Net 框架是 4.5.2 和服务器:windows server 2008 r2 托管应用程序。

#region To handle TLS (Transport Layer Security) Version and support
            var assembly = Assembly.GetExecutingAssembly();
            var attributes = assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
            var version = (TargetFrameworkAttribute)attributes[0];

            SecurityProtocolType flag;
            if (Enum.TryParse("Tls11", out flag))
                ServicePointManager.SecurityProtocol |= flag;
            if (Enum.TryParse("Tls12", out flag))
                ServicePointManager.SecurityProtocol |= flag;
#endregion

谢谢。

【讨论】:

【参考方案11】:
    更新 Windows 和 WinHTTP 确保在操作系统级别启用 TLS 1.2 作为 SChannel 协议 更新和配置 .NET Framework 以支持 TLS 1.2
    https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-wi
    https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings
    https://docs.microsoft.com/en-us/mem/configmgr/core/plan-design/security/enable-tls-1-2-client

【讨论】:

以上是关于.Net Framework 4.6.1 不默认为 TLS 1.2的主要内容,如果未能解决你的问题,请参考以下文章

我可以将 C# 7.3 与 .Net Framework 4.6.1 一起使用吗?

如何将针对 Entity Framework .Net 4.6.1 的库与 .Net Core 应用程序一起使用

Win10企业版安装NET Framework时出现"这台计算机中已经安装了.NET Framework 4.6.1或版本更高的更新"错误

netstandard2.0 (.net standard 2.0) 类库不能引用 net461 (.net framework 4.6.1) 类库

使用 .NET Core(.NET Standard 1.4 和 .NET Framework 4.6.1)对 System.Net.Http 使用 await/async 时出现错误?

在库中使用 .Net Standard 1.4 和在应用程序中使用 .Net framework 4.6.1 时,无法加载文件 System.IO.FileSystem,Version=4.0.1.0