首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过App.config为System.Net.HttpWebRequest指定SSL/TLS

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

Stack Overflow用户
提问于 2017-08-04 02:31:56
回答 3查看 12.5K关注 0票数 9

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

如果不指定SecurityProtocol,将使用底层操作系统协议,但它们似乎缺省为最不安全的协议,而不是最安全的。因为我在机器上运行了多个服务,所以我不能将操作系统设置为只使用TLS1.2,但我仍然希望这个特定的客户端使用TLS1.2,并且当TLS1.3出现时,能够通过特定于应用程序的配置对其进行修改。

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

这个问题解释了如何通过整个机器的注册表设置来完成此操作:Are there .NET implementation of TLS 1.2?

代码语言:javascript
复制
// 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中涵盖的,但我找不到对应的。

代码语言:javascript
复制
<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更新,但很快就遇到了同样的问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-09 09:04:34

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
<appSettings>
    <add key="SecurityProtocol" value="3072" />
</appSettings>
票数 2
EN

Stack Overflow用户

发布于 2019-05-02 00:22:48

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

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

如果无法重定目标或重新编译应用程序,则可以通过在通常名为«ExecutableName».exe.configapp.config中添加或编辑来手动指定这些兼容性开关的值。交换机DontEnableSystemDefaultTlsVersions是在.net-4.7中添加的,它支持使用系统提供的TLS策略。交换机DontEnableSchUseStrongCrypto是在.net-4.6中添加的,它添加了对TLS1.2的支持。

代码语言:javascript
复制
<?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>
票数 9
EN

Stack Overflow用户

发布于 2018-06-22 06:14:58

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

代码语言:javascript
复制
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

代码语言:javascript
复制
<appSettings>
    <add key="SecurityProtocol" value="Tls12" />
</appSettings>
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45492000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档