HttpWebRequest 始终发送 TLS 1.0
HttpWebRequest always sending TLS 1.0
我正在使用 HttpWebRequest 连接到第 3 方 API 并遇到失败 ("Underlying Connection closed") API 不支持用于请求的 TLS 版本.我检查了 Fiddler 中的请求,发现我的请求正在发送 TLS 1.0。
我已经尝试在全局 ServicePointManager
上设置较新的 TLS / SSL 版本,正如 SO 上许多许多答案中所建议的那样(并尝试了许多不同的设置方式),但即使在设置之后在发出请求之前,我仍然遇到相同的错误,我在 Fiddler 中检查并看到请求是 still 使用 TLS 1.0!。这就像我尝试使用 ServicePointManager 根本没有任何效果。
我发出请求的 DLL 在 .NET 4.6.1 上,并且也在 .NET 4.6.1 上使用 DLL,所以我不认为框架版本是罪魁祸首。
非常感谢任何想法或指导!!!
框架是罪魁祸首。问题是 .NET Framework 从 4.6 版开始不允许使用 SSL,因为它被认为是易受攻击的。
解决方法
要解决此问题,请将服务器更新到 Tls 1.0、Tls 1.1 或 Tls 1.2,因为 SSL 3.0 已被证明不安全并且容易受到 POODLE 等攻击。
注意如果您无法更新服务器,请使用 AppContext class 选择退出此功能。
为此,请使用以下方法之一:
编程方式:必须是应用程序做的第一件事,因为 ServicePointManager 只会初始化一次。在您的应用程序中使用以下代码示例:
private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching";
private const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto";
AppContext.SetSwitch(DisableCachingName, true);
AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, true);
通过为您的应用程序使用 AppConfig 文件:将以下行添加到 Appconfig 文件:
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=true"/>
有关下面 link 的更多信息。
我在开发 Android 应用程序时遇到了类似的问题。
事实证明,我必须专门关闭 TLS 1.0,然后才能尝试更新版本的 TLS。我认为这是一个愚蠢的问题,但我最终所做的工作奏效了,所以我不会抱怨太多。
第一篇文章包含很多 link 到有关审核代码的页面,以查看您使用的方法是否专门将您锁定在 TLS 1.0 中,就好像您不小心将其硬编码一样。
如果您使用的是自定义绑定:
- 配置 WCF 以允许 OS 选择最佳安全协议
将 SslProtocols 设置为使用 SslProtocols.None.
- 或者配置与配置路径系统一起使用的协议。serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols.
如果您没有使用自定义绑定,而是使用配置设置 WCF 绑定,请设置用于配置路径系统的协议。serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols。
对于 .NET Framework 4.6 - 4.6.2 而不是 WCF
将 DontEnableSystemDefaultTlsVersions AppContext 开关设置为 false。请参阅通过 AppContext 开关配置安全性。
对于使用 .NET Framework 4.6 - 4.6.2 的 WCF,使用带有证书凭据的 TCP 传输安全性
您必须安装最新的 OS 补丁。请参阅安全更新。
除非您明确配置协议版本,否则 WCF 框架会自动选择最高可用的 TLS 1.2 协议。有关详细信息,请参阅前面的部分对于使用具有证书凭据的传输安全性的 WCF TCP 传输。
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
上面的页面 link 到下面的 link,专门用于从您的项目中删除 TLS 1.0 依赖项以迁移到 TLS 1.2+。
https://www.microsoft.com/en-us/download/details.aspx?id=55266
- Identify all instances of AcquireCredentialsHandle(). This helps reviewers get closer proximity to code blocks where TLS may be hardcoded.
- Review any instances of the SecPkgContext_SupportedProtocols and SecPkgContext_ConnectionInfo structures for hardcoded TLS.
- In native code, set any non-zero assignments of grbitEnabledProtocols to zero. This allows the operating system to use its default TLS version.
- Disable FIPS Mode if it is enabled due to the potential for conflict with settings required for explicitly disabling TLS 1.0/1.1 in this document. See Appendix B for more information.
- Update and recompile any applications using WinHTTP hosted on Server 2012 or older.
a. Applications must add code to support TLS 1.2 via WinHttpSetOption
- To cover all the bases, scan source code and online service configuration files for the patterns below corresponding to enumerated type values commonly used in TLS hardcoding:
a. SecurityProtocolType
b. SSLv2, SSLv23, SSLv3, TLS1, TLS 10, TLS11
c. WINHTTP_FLAG_SECURE_PROTOCOL_
d. SP_PROT_
e. NSStreamSocketSecurityLevel
f. PROTOCOL_SSL or PROTOCOL_TLS
这就是文档的主要内容,但还不止于此。我建议检查一下并确保您没有意外犯错,或者您有遗留代码阻止您继续前进。这可能有点重写,而不仅仅是一个设置,祝你好运!
我认为您可能需要更改注册表设置
请点击以下参考链接
From Whosebug
我正在使用 HttpWebRequest 连接到第 3 方 API 并遇到失败 ("Underlying Connection closed") API 不支持用于请求的 TLS 版本.我检查了 Fiddler 中的请求,发现我的请求正在发送 TLS 1.0。
我已经尝试在全局 ServicePointManager
上设置较新的 TLS / SSL 版本,正如 SO 上许多许多答案中所建议的那样(并尝试了许多不同的设置方式),但即使在设置之后在发出请求之前,我仍然遇到相同的错误,我在 Fiddler 中检查并看到请求是 still 使用 TLS 1.0!。这就像我尝试使用 ServicePointManager 根本没有任何效果。
我发出请求的 DLL 在 .NET 4.6.1 上,并且也在 .NET 4.6.1 上使用 DLL,所以我不认为框架版本是罪魁祸首。
非常感谢任何想法或指导!!!
框架是罪魁祸首。问题是 .NET Framework 从 4.6 版开始不允许使用 SSL,因为它被认为是易受攻击的。
解决方法
要解决此问题,请将服务器更新到 Tls 1.0、Tls 1.1 或 Tls 1.2,因为 SSL 3.0 已被证明不安全并且容易受到 POODLE 等攻击。
注意如果您无法更新服务器,请使用 AppContext class 选择退出此功能。
为此,请使用以下方法之一:
编程方式:必须是应用程序做的第一件事,因为 ServicePointManager 只会初始化一次。在您的应用程序中使用以下代码示例:
private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching";
private const string DontEnableSchUseStrongCryptoName = @"Switch.System.Net.DontEnableSchUseStrongCrypto";
AppContext.SetSwitch(DisableCachingName, true);
AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, true);
通过为您的应用程序使用 AppConfig 文件:将以下行添加到 Appconfig 文件:
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=true"/>
有关下面 link 的更多信息。
我在开发 Android 应用程序时遇到了类似的问题。
事实证明,我必须专门关闭 TLS 1.0,然后才能尝试更新版本的 TLS。我认为这是一个愚蠢的问题,但我最终所做的工作奏效了,所以我不会抱怨太多。
第一篇文章包含很多 link 到有关审核代码的页面,以查看您使用的方法是否专门将您锁定在 TLS 1.0 中,就好像您不小心将其硬编码一样。
如果您使用的是自定义绑定:
- 配置 WCF 以允许 OS 选择最佳安全协议
将 SslProtocols 设置为使用 SslProtocols.None.
- 或者配置与配置路径系统一起使用的协议。serviceModel/bindings/customBinding/binding/sslStreamSecurity:sslProtocols.
如果您没有使用自定义绑定,而是使用配置设置 WCF 绑定,请设置用于配置路径系统的协议。serviceModel/bindings/netTcpBinding/binding/security/transport:sslProtocols。
对于 .NET Framework 4.6 - 4.6.2 而不是 WCF
将 DontEnableSystemDefaultTlsVersions AppContext 开关设置为 false。请参阅通过 AppContext 开关配置安全性。
对于使用 .NET Framework 4.6 - 4.6.2 的 WCF,使用带有证书凭据的 TCP 传输安全性
您必须安装最新的 OS 补丁。请参阅安全更新。
除非您明确配置协议版本,否则 WCF 框架会自动选择最高可用的 TLS 1.2 协议。有关详细信息,请参阅前面的部分对于使用具有证书凭据的传输安全性的 WCF TCP 传输。
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
上面的页面 link 到下面的 link,专门用于从您的项目中删除 TLS 1.0 依赖项以迁移到 TLS 1.2+。
https://www.microsoft.com/en-us/download/details.aspx?id=55266
- Identify all instances of AcquireCredentialsHandle(). This helps reviewers get closer proximity to code blocks where TLS may be hardcoded.
- Review any instances of the SecPkgContext_SupportedProtocols and SecPkgContext_ConnectionInfo structures for hardcoded TLS.
- In native code, set any non-zero assignments of grbitEnabledProtocols to zero. This allows the operating system to use its default TLS version.
- Disable FIPS Mode if it is enabled due to the potential for conflict with settings required for explicitly disabling TLS 1.0/1.1 in this document. See Appendix B for more information.
- Update and recompile any applications using WinHTTP hosted on Server 2012 or older. a. Applications must add code to support TLS 1.2 via WinHttpSetOption
- To cover all the bases, scan source code and online service configuration files for the patterns below corresponding to enumerated type values commonly used in TLS hardcoding:
a. SecurityProtocolType
b. SSLv2, SSLv23, SSLv3, TLS1, TLS 10, TLS11
c. WINHTTP_FLAG_SECURE_PROTOCOL_
d. SP_PROT_
e. NSStreamSocketSecurityLevel
f. PROTOCOL_SSL or PROTOCOL_TLS
这就是文档的主要内容,但还不止于此。我建议检查一下并确保您没有意外犯错,或者您有遗留代码阻止您继续前进。这可能有点重写,而不仅仅是一个设置,祝你好运!
我认为您可能需要更改注册表设置 请点击以下参考链接
From Whosebug