C# 当服务器响应TLS 1.1时,.net 4.7无法创建SSL通道

C# 当服务器响应TLS 1.1时,.net 4.7无法创建SSL通道,c#,ssl,https,.net-4.6.2,.net-4.7,C#,Ssl,Https,.net 4.6.2,.net 4.7,我正在尝试使用客户端证书身份验证执行HTTPS GET请求,但失败了 The request was aborted: Could not create SSL/TLS secure channel. 我正在使用Java尝试相同的请求,它运行良好,我在Java日志中看到了以下内容(仅剥离到有趣的部分): 据我所知,这意味着服务器出于某种原因不支持TLS1.2,但客户机接受了这一点,并简单地退回到TLS1.1 当我设定 ServicePointManager.SecurityProtocol =

我正在尝试使用客户端证书身份验证执行HTTPS GET请求,但失败了

The request was aborted: Could not create SSL/TLS secure channel.
我正在使用Java尝试相同的请求,它运行良好,我在Java日志中看到了以下内容(仅剥离到有趣的部分):

据我所知,这意味着服务器出于某种原因不支持TLS1.2,但客户机接受了这一点,并简单地退回到TLS1.1

当我设定

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
.NET也很好用。 现在的问题是-为什么.NET没有像Java那样回退到TLS1.1,我是否可以以某种方式启用这种回退(而不实际尝试TLS1.2,捕获异常并尝试使用TLS1.1)?

在对它的描述中已经说明

请注意,没有为此属性列出任何默认值。 安全环境不断变化,默认协议和 保护级别会随着时间的推移而改变,以避免已知的 弱点。默认值将因机器而异 配置,以及在哪个软件上安装,以及在哪个软件上安装 已应用补丁程序

您的代码永远不应该隐式依赖于 使用特定的保护级别,或假设 默认情况下使用安全级别。如果你的应用程序依赖于 对于特定的安全级别,必须明确指定该级别和 然后检查以确保它在已建立的系统上实际使用 连接。此外,您的代码应该设计为在 面对支持协议的更改,例如 通常在很少提前通知的情况下进行,以缓解出现的问题 威胁

在.NET 4.7上,此属性的默认值应为
SystemDefault
(),
SystemDefault
表示“向操作系统询问默认协议列表”(在Windows 10上,TLS 1.1和TLS 1.2是)-此值仍可能受多个外部源的影响(例如注册表项,正如您在上面看到的,即使是安装的软件或应用的补丁程序)。正如我们在评论中指出的,出于某种原因,默认情况下,您将其命名为
Ssl3 | Tls
,这是不好的,因为
Ssl3
甚至不安全,应该禁用

因此,为了解决您的问题(以及在将来的情况下),请始终列出您需要的协议,尤其是在多台客户端计算机上发布应用程序时,因为默认设置不可靠:

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

将SecurityProtocol设置为SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12?顺便问一下,在运行此代码的计算机上安装的Windows版本是什么?Windows 10 15063.608非常有趣,不知道SecurityProtocolType被标记为标志!并且通过defau将值设置为SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12有效它是SSL3 | Tls。如果您将评论转换为答案,我会将其标记为已确认;)另外,有趣的是,项目是.net 4.7,根据这里的说明,它的行为与.net 4.5相同:另外,在Windows 10上使用.net 4.7时,这里似乎也提到了同样的问题:@Giedrius。但这似乎并不一致。例如,我的Windows版本与您相同,但在.NET 4.7上默认使用SystemDefault
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;