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

问题描述 投票:5回答:3

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

如果未指定SecurityProtocol,则使用基础操作系统协议,但它们似乎默认为最不安全而不是最安全。因为我有从机器运行的多个服务,所以我无法将操作系统设置为仅使用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更新,但很快遇到了同样的问题。

.net httpwebrequest webclient app-config dotnet-httpclient
3个回答
3
投票

使用协议名称而不是整数代码的示例。

string securityProtocol = ConfigurationManager.AppSettings["SecurityProtocol"].ToString();

try
{
    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)Enum.Parse(typeof(System.Net.SecurityProtocolType), securityProtocol);
}
catch (Exception ex)
{
    Console.WriteLine("Could not setup SecurityProtocol. Try a different integer value: " + ex.Message);
    foreach (System.Net.SecurityProtocolType protocolType in Enum.GetValues(typeof(System.Net.SecurityProtocolType)))
    {
        Console.WriteLine(string.Foramt("SecurityProtocol: {0} - {1}", protocolType.ToString(), (int)protocolType));
    }
}

对于App.Config

<appSettings>
    <add key="SecurityProtocol" value="Tls12" />
</appSettings>

2
投票

现在我在App.config中放了一个整数值,它指定了将System.Net.ServicePointManager.SecurityProtocol设置为的枚举值。我仍然认为可能有更优雅的方式来做到这一点并期待其他答案。我被https://stackoverflow.com/a/35325333/5221761引导到了这个方向

int securityProtocol = Convert.ToInt32(ConfigurationManager.AppSettings["SecurityProtocol"]);

try
{
    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)securityProtocol;
}
catch(Exception ex)
{
    Console.WriteLine("Could not setup SecurityProtocol. Try a different integer value: " + ex.Message);
    foreach (System.Net.SecurityProtocolType protocolType in Enum.GetValues(typeof(System.Net.SecurityProtocolType)))
    {
        Console.WriteLine(string.Foramt("SecurityProtocol: {0} - {1}", protocolType.ToString(), (int)protocolType));
    }
}

App.config中:

<appSettings>
    <add key="SecurityProtocol" value="3072" />
</appSettings>

0
投票

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

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

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

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.