.net - 通过 App.config 为 System.Net.HttpWebRequest 指定 SSL/TLS

标签 .net httpwebrequest webclient app-config dotnet-httpclient

我需要将 JSON 数据发布到 TLS 1.2 端点。我希望在 App.config 中指定 SecurityProtocol,而不是在源代码中进行硬编码,并且不想将机器的注册表设置为禁用 TLS 1.1。

如果您未指定 SecurityProtocol,则使用底层操作系统协议(protocol),但它们似乎默认为最不安全而不是最安全。因为我从机器上运行了多个服务,所以我无法将操作系统设置为仅使用 TLS1.2,但我仍然希望这个特定的客户端使用 TLS 1.2,并且当 TLS 1.3 出现时,可以通过应用程序特定的配置对其进行修改。

这个问题通过代码解释了如何做到这一点:How to specify SSL protocol to use for WebClient class

这个问题解释了如何通过整个机器的注册表设置来做到这一点:Are there .NET implementation of TLS 1.2?

// this is what I want to avoid
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocol.Tls12;

System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);

using (System.IO.StreamWriter sw = new System.IO.StreamWriter(request.GetRequestStream()))
{
    sw.write(json);
}

System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
using System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
{
    content = sr.ReadToEnd();
}

目前,我的 App.config 中没有针对此客户端的任何内容,但这就是我想要更改的内容。

我发现system.serviceModel中有一个sslStreamSecurity元素,但我相信这是针对ServiceReferences的,而不是普通的HttpWebRequest。我相信 system.net 涵盖了这一点,但我找不到等价物。
<system.serviceModel>
  <bindings>
    <customBinding>
      <binding name="myBinding">
        <sslStreamSecurity sslProtocls="Tls12">
      </binding>
    </customBinding>
  </bindings>
  <client>
    <endpoint address="https://myserver.com" binding="customBinding" bindingConfiguration="myBinding" name="myEndpoint" />
  </client>
</system.ServiceModel>

我对使用 HttpWebRequest/HttpWebResponse 以外的东西持相当开放的态度,但不想安装第三方包。我从 System.Net.Http.HttpClient 开始。这似乎比 HttpWebRequest 更新,但很快遇到了同样的问题。

最佳答案

可以通过编辑 app.config 来更改针对 <.net-4.6 的应用程序的 TLS 设置,而无需重新编译它。只要您在≥.net-4.6 上运行它。这记录在 “Transport Layer Security (TLS) best practices with the .NET Framework” .

当 Microsoft 开发 .net-4.6 作为 .net-4.5 的就地替代品时,他们希望进行行为更改,包括错误修复、安全改进等。但他们不想破坏依赖于 .net-4.5 的应用程序旧行为——甚至是有缺陷的行为(旧代码依赖于有缺陷的行为是很常见的,Microsoft 的 .net 团队非常关心为了兼容性而有目的地保留缺陷)。要做到这一点,从 .net-4.6 开始并继续后续版本,每个预期会导致兼容性问题的新行为更改都放置在启用旧行为的开关后面,默认为 true .在编译时,目标框架存储在程序集中。当运行时加载入口点的程序集时,它会检查目标版本,然后自动为目标 .net 版本预设其兼容性开关。

如果您无法重新定位或重新编译您的应用程序,您可以通过添加或编辑 <AppContextSwitchOverrides/> 手动指定这些兼容性开关的值。在 app.config通常命名为 «ExecutableName».exe.config .开关DontEnableSystemDefaultTlsVersions在支持使用系统提供的 TLS 策略的 .net-4.7 中添加。开关DontEnableSchUseStrongCrypto在 .net-4.6 中添加,增加了对 TLS 1.2 的支持。

<?xml version="1.0"?>
<configuration>
  <runtime>
    <!--
      Support connecting to servers which require modern TLS protocols.

      DontEnableSystemDefaultTlsVersions=false is sufficient if running on ≥.net-4.7
      which supports using the system-provided TLS versions/policies.
      DontEnableSchUseStrongCrypto is required if running on .net-4.6 which defaults
      to newer versions of TLS but doesn’t support following system updates/policies.
     -->
    <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
  </runtime>
</configuration>

关于.net - 通过 App.config 为 System.Net.HttpWebRequest 指定 SSL/TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45492000/

相关文章:

c# - HttpWebRequest 限制?或者实现不当

java - 在PHP中读取Java发送的HttpRequest

c# - 无法将下载的文件保存到 WPF C# 中的桌面

c# - 加载 Microsoft.AspNet.WebApi.Client System.Net.Http.Formatting.dll 时尝试为 T4 文件查找 "missing dependency"

面向中级 .NET 开发人员的 Java

.net - 监听相同端口、不同 IP 地址、WCF + 非 WCF 应用程序

c# - Parallel.ForEach 在与 BlockingCollection 集成时停止

c# - 在openxml中为Excel添加样式

javascript - 如何从 Windows 窗体应用程序调用 Web API 登录操作

c# - 使用 WebClient.UploadFile 时无响应