ChatGPT解决这个技术问题 Extra ChatGPT

.NET 4.5 中的默认安全协议

与最多支持 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.01.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 Q&A:stackoverflow.com/questions/41618766/… 读者应注意,这个问题已经过时了,新的建议自 2020 年起已经到位。

S
Scott

一些对其他答案发表评论的人指出,将 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
L
Luke Hutton

.NET 4.0/4.5 中的默认 System.Net.ServicePointManager.SecurityProtocolSecurityProtocolType.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 值)

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

因此,我决定删除对 SSLv3 的支持的最佳途径是:

将所有应用程序升级到 .NET 4.5 将以下内容添加到引导代码以覆盖默认值和未来证明:System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Tls11 |安全协议类型.Tls12;

*如果这个黑客是错误的,有人纠正我,但我看到它的初始测试有效


请参阅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 上,根据 support.microsoft.com/en-us/help/3069494/…,默认值现在是 SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12
F
Franklin Yu

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

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+ 中的默认行为是使用强加密;在这种情况下,此注册表项仅可用作禁用强加密的一种手段。
d
dana

创建一个带有 .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 请求上失败。这些键解决了我们的问题。
J
Jim

我发现当我只指定 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 添加
M
Marcel

以下代码将:

打印启用协议

打印可用的协议

启用 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

H
Hieu

当我的客户将 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-and-server-2008-r2-sp1


是否可以在不更改源代码的情况下更改 SecurityProtocol?像 machine.config 或 app.config。
哇。那是年度巫术奖……东西……就在那里。你摇滚郊区!
U
Uwe Keim

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

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

https://i.stack.imgur.com/NGeTH.png


这不准确。对于 .NET 4.5.2,这需要设置为 1(或更高);但对于 .NET 4.6,不设置为 0 就足够了(即可以取消设置)。
哦,我没有在 .Net 4.6 中测试。我的发现在博文 joymonscode.blogspot.com/2015/08/…
您提到的注册表项应为“Wow6432Node”。由于某种原因,您省略了“节点”部分。我试图编辑您的回复,但我的更改只有 4 个字母,所以它不会让我这样做。 :\
我不得不反弹 IIS 以使此设置本身作为默认设置处于活动状态。
R
Roger Sanders

我在 .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 “允许操作系统选择要使用的最佳协议,并阻止不安全的协议”。
J
JohnLBevan

微软最近发布了关于此的最佳实践。 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\TLS 1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

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


问题是,如果您遵循指南(保持 SecurityProtocolType.SystemDefault),tls 1.1 和 tls 1.2 将无法在 Windows 7 和 Server 2008 上运行,因为在没有更改注册表的情况下,它们在这些操作系统中未“启用”(无论这意味着什么)。这使得 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;
q
qbik

为了完整起见,这是一个设置上述注册表项的 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"

S
Sagar Borole

有两种可能的情况,

如果您的应用程序在 .net framework 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>

V
Vikrant

硬编码 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

G
G W C

此问题的最佳解决方案似乎是至少升级到 .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。
B
Benjamin Freitag

根据 Transport Layer Security (TLS) best practices with the .NET Framework为确保 .NET Framework 应用程序保持安全,TLS 版本不应被硬编码。 而是设置注册表项:SystemDefaultTlsVersions SchUseStrongCrypto

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

y
yanivhs

如果您可以使用 .NET 4.7.1 或更高版本,它将使用 TLS 1.2 作为基于操作系统功能的最低协议。根据微软的建议:

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.

k
kgw

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

您必须将值设置为 1。


我认为您被否决了,因为它与@Jira Mares 提供的答案相同,但细节较少