.NET v4.7 不存在 TLS1.2

TLS1.2 does not exist with .NET v4.7

我收到一个未处理的异常 The request was aborted: could not create SSL/TLS secure channel 所以我正在尝试使用 Tls1.2 希望它能解决这个问题。

我了解到 .NET 4.6 及更高版本的默认设置是 TLS1.2

我的版本是 4.7,我的代码中有行 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;,但在 .Tls12 下有一个红色衬垫。 Visual Studio 说 SecurityProtocolTypes does not contain a definition for Tls12 并建议我将 .Tls12 替换为 .Tls

如何在我的代码中使用 Tls1.2?

我应该补充一点,我也尝试过: ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0|0x300 0xc00);

你读过 Transport Layer Security (TLS) best practices with the .NET Framework 了吗?

它说:

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.

以后:

If your app targets .NET Framework 4.7 or later versions

The following sections show how to verify you're not using a specific TLS or SSL version.

For HTTP networking

ServicePointManager, using .NET Framework 4.7 and later versions, defaults to the OS choosing the best security protocol and version. To get the default OS best choice, if possible, don't set a value for the SecurityProtocol property. Otherwise, set it to SystemDefault.

所以如果默认情况下它不起作用......也许你真的没有使用 4.7?

或者您的操作系统太旧以至于不支持它?

或者目标不支持?

无论哪种方式,都不需要明确将其设置为 1.2

@nvoigt 正确回答了这个问题,但我想我会分享我最近的经验,因为它非常相似,但有一点不同。

背景故事: 我有一个针对 .net 3.5 开发的应用程序,它是使用 Visual Studio 2013,更新 1 构建的。这是为了与另一个应用程序兼容。在该应用程序中,它使用了一个已更新为使用 TLS 1.2 的端点。因为 .net 3.5 不支持 TLS 1.2,我们不得不解决这个问题。

根据@nvoigt 发布的答案(以及与此相关的网络其他内容),我了解到升级应用程序以针对更新的 .net 框架(在我的例子中是 4.7.1)将解决问题,因为只要我们没有在我们的应用程序中硬编码任何这些协议。这将允许 OS 指示协议。

问题: 使用 Visual Studio 2013,更新 1 - 我将我们应用程序的目标框架更新为 .net 4.7.1 并验证 ServicePointManager.SecurityProtocol 没有在任何地方进行硬编码,因此它会推迟到 OS. 这不管用,不管我在网上读了多少文章说它会。

分辨率: 使用 Visual Studio 2019 - 我打开并测试了仍然以 .net 4.7.1 为目标的完全相同的应用程序,除了用于编译项目的 Visual Studio 版本之外没有其他更改。 这确实有效!

我的发现: 我想消除我的特定项目中可能导致此问题的其他原因的任何可能性。为此,我创建了一个 全新的 windows 表单项目,并在 Program class 的 static void Main() 方法中设置了以下内容变量 var x = ServicePointManager.SecurityProtocol; 以查看默认设置的值。这是我对新项目所做的唯一修改。然后,我继续在 Visual Studio 2013 和 Visual Studio 2019 中调试完全相同的新项目(两者仍以 .net 4.7.1 为目标),我得到如下所示的结果:

Visual Studio 2013 -(针对 .net 4.7.1)

var x = ServicePointManager.SecurityProtocol;
//  ^ x defaults to 'Ssl3 | Tls'

Visual Studio 2019 -(针对 .net 4.7.1)

var x = ServicePointManager.SecurityProtocol;
//  ^ x defaults to 'SystemDefault'

请参阅下面的并排屏幕截图(左侧为 VS 2013,右侧为 VS 2019):

即使我在 Visual Studio 2013 年手动设置 ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; 也无法正常工作!让它在 Visual Studio 2013 年工作的唯一方法是像这样硬编码协议 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 我们都知道这不是最佳实践。

经验教训: 当您知道其他方法似乎不起作用时,请使用较新版本的 Visual Studio 编译您的应用程序进行测试,或确保您使用的版本应用了最新更新。