背景介绍

近期收到同事反馈,在C#程序中通过HTTPClient请求一个HTTPS的地址时,在本地开发环境和测试环境均能正常执行,而部署到生产环境后发生异常且稳定复现,异常提示为:【请求被中止: 未能创建 SSL/TLS 安全通道 】,而且在生产环境用浏览器访问是没问题的。

目标站点和运行环境介绍

  • 目标站点SiteA(同事对接的站点):jc.ebopark.com
  • 目标站点SiteB(对比站点):www.howsmyssl.com
  • 生产环境服务器MA1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自Azure
  • 测试环境服务器T1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自Azure
  • 本地临时VMware虚拟机VM1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自微软官网

初步分析

自然的,根据异常信息先进行一圈Google(不用百度),基本都是在说ServicePointManager.SecurityProtocol的赋值,但是本次的程序中已经配置了全部协议。在了解了大概背景之后,基本断定该故障与源码本身的关系不大,仔细检查源码后也确实没有问题。大家也能看得出,很明显的环境不同导致的故障,那么宿主环境的差异就是我们优先要排查分析的线索。

这里要引入HTTPS的一些知识点

1、关于HTTP、HTTPS、TLS的关系:HTTPS连接是由HTTP协议与TLS协议共同完成。

2、建立HTTPS连接不仅需要Client与Server双方的TLS协议版本号兼容,还需要Cipher Suites(密码套件)兼容。关于什么是Cipher Suites可以自行查阅资料,本文不详细展开说明。Cipher Suites的样子如图所示:

进一步验证

有了以上理论支撑,下面就开始对本次案例的站点和运行环境进行一一分析;

首先,通过在线工具验证目标站点SiteA自身的HTTPS连接功能是否OK:

截图报告显示SiteA支持TLS1.2、TLS1.3协议,同时也可以看到对应的密码套件。说明该站点自身配置没问题,这也符合同事的测试结果。

根据前面提到的知识点,下一步就需要判断连接的Client端(即C#应用)所支持的协议和密码套件。先看在程序中配置的是支持TLS全协议:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12 |
(SecurityProtocolType) 12288;

其次查看运行时部署的.NET Framework 4.8对TLS的兼容情况,如下图所示,环境对TLS1.2、TLS1.3均支持。

现在TLS协议看起来是兼容的,那么该如何查看C#应用所使用的密码套件?这里用到一个工具:IISCrypto.exe

生产环境服务器MA1的密码套件如下图所示。经过仔细对比,该OS没有与目标站点SiteA匹配的密码套件,因此无法建立连接,符合实际情况。

测试环境服务器T1的密码套件如下图所示。该OS中有2组和目标站点SiteA的TLS1.2密码套件匹配,因此可以建立链接,符合实际情况。

本地临时VMware虚拟机VM1的密码套件如下图所示,该OS中有多组和目标站点SiteA的TLS1.2密码套件匹配,因此可以建立链接,符合实际情况。

经过上述对比后,基本可以判定是由于生产环境的服务器密码套件与目标站点不匹配导致。

解决方案比较简单,使用IISCrypt工具把缺少的密码套件勾选,并择机重启服务器生效即可。

延伸1:如何创建TLS1.3协议的连接?

根据前面对几台服务器的密码套件的分析,兼容的密码套件都是最多是TLS1.2版本的,那是否真可以创建TLS1.3的连接呢?所幸我本地开发环境比较新,是Windows11,经过查看密码套件可以兼容TLS1.3:

使用工具在只选择TLS1.3协议的情况下,验证是可以成功请求的:

延申2:Edge浏览器所支持的密码套件自带的,独立于Windows。

下图是生产环境服务器MA1上的Edge浏览器的密码套件支持情况。

通过该浏览器直接请求目标站点SiteA,不仅可以请求成功而且还是走的TLS1.3协议。

总结

本文针对实际开发中遇到怪异现象,结合HTTPS的理论知识,透彻的分析了故障原因并最终解决。本文中还提到了几个实用的工具,可以更方便的查看相关细节。最后针对生产服务器镜像默认的密码套件问题,后续会继续与运维同事反馈并更新。

参考资料:

  • 查看TLS在线工具:https://myssl.com/ssl.html
  • IISCrypto官网:https://www.nartac.com/Products/IISCrypto/
  • .NET Framework 中的传输层安全性 (TLS) 最佳做法:https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
  • 查看当前连接的tls信息-API版:https://www.howsmyssl.com/a/check

附:苹果推送服务API的TLS信息

C#请求HTTPS地址的故障分析和TLS知识点总结的更多相关文章

  1. java请求https地址如何绕过证书验证?

    原文http://www.blogjava.net/hector/archive/2012/10/23/390073.html 第一种方法,适用于httpclient4.X 里边有get和post两种 ...

  2. 通过证书请求Https站点

    前几天在做与平安银行对接接口,主要是给平安银行推送用户数据(申请贷款的用户),平安银行提供的是https的地址,请求https地址的时候还要发送证书,刚接到这个任务的时候一头雾水,百度上各种所搜,最后 ...

  3. [Delphi]实现使用TIdHttp控件向https地址Post请求[转]

    开篇:公司之前一直使用http协议进行交互(比如登录等功能),但是经常被爆安全性不高,所以准备改用https协议.百度了一下资料,其实使用IdHttp控件实现https交互的帖子并不少,鉴于这次成功实 ...

  4. 彻底解决:请求被中止: 未能创建 SSL/TLS 安全通道

    最近有个项目要调用客户用java写的带https的webservice,对方提供了证书文件 test.pfx,我这里调用方式如下: //webservice代理类 SvcService svc = n ...

  5. HttpWebRequest请求Https协议的WebApi

    public static class RequestClient { /// <summary> /// 参数列表转为string /// </summary> /// &l ...

  6. C# 解决“请求被中止: 未能创建 SSL/TLS 安全通道”的问题

    最近在开发项目的时候,使用爬虫抓取网络数据的时候,当请求Web数据时,碰到了“请求被中止: 未能创建 SSL/TLS 安全通道”的问题,尝试过很多网上的方法,例如添加证书等都没有用.最后在GitHub ...

  7. 带jsk证书,请求https接口

    首先是三个返回的实体类 BaseVo.java package https2; import java.io.Serializable; import java.lang.reflect.Invoca ...

  8. .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

    前言: 前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题.背景,关于调用第三方的接口都是使用使 ...

  9. 通过HttpWebRequest请求https接口

    一.为什么进行代理接口的开发: 有些项目需要访问被墙了哒网站,比如前不久公司开发项目需要使用google地图的接口,而google在中国被墙了,所有打算做一个代理接口服务,将代理放到国外服务器上,通过 ...

随机推荐

  1. Python 迭代器、生成器、可迭代对象

    迭代器 1 #迭代器定义: 2 #类中得有__iter__和__next__两个方法 3 #__iter__方法放回对象本身,即:self(是迭代器对象) 4 #__next__方法,返回下一个数据, ...

  2. 搭建PWN学习环境

    环境清单 系统环境 Ubuntu22.04 编写脚本 pwntools ZIO 调试 IDA PRO gdb pwndbg ROP工具 checksec ROPgadget one_gadget Li ...

  3. .net 关于Task.Run 和 Async await的执行顺序

    一直捋不清楚用Task.Run异步的执行关系,网上找的些说明写得也有点复杂,所以自己做实验测一下. 直接上代码 这个是加await private static void TestFun() { Co ...

  4. HMS Core地理围栏能力助你实现指定范围人群的精准消息推送

    精准推送是移动端产品留存阶段的主要运营手段,精准推送常常会与用户画像紧密结合,针对用户的喜好.画像,采用不同策略,但基于用户所属区域推送消息却很难实现.目前市面上大多数第三方消息推送服务商,在系统未深 ...

  5. java、selenium、图片滑块验证,底部附本地可测试代码

    准备 本地Chrome版本对应WebDriver驱动:http://chromedriver.storage.googleapis.com/index.html maven包 <!-- sele ...

  6. tomcat 1.2 负载均衡

    实验效果:访问同一个ip或域名,轮询显示两个不同的tomcat界面, nginx服务器ip:192.168.213.4       tomcat服务器ip:192.168.213.3 实验环境:两台服 ...

  7. 讨论两种Redis中Token的存储方式

    摘要:本文讨论一个问题:存储token时,token与对应用户id谁来作为key? 问题起源问题起源于要给公司的后台管理系统添加权限管理,选用的是开源框架shiro,而原本系统上是采用token做了登 ...

  8. 超级简单!CentOS-8 安装 MySQL 8.0,比喝水还简单

    中国人不骗中国人 果然是系统和MySQL的版本越高安装越便利了 在阿里云的 CentOS-8 比喝开水还简单的安装 MySQL 8.0,开始~ 1.以 root 用户通过 CentOS 软件包管理器来 ...

  9. 实践torch.fx第一篇——基于Pytorch的模型优化量化神器

    第一篇--什么是torch.fx 今天聊一下比较重要的torch.fx,也趁着这次机会把之前的torch.fx笔记整理下,笔记大概拆成三份,分别对应三篇: 什么是torch.fx 基于torch.fx ...

  10. 【SpringCloud原理】万字剖析OpenFeign之FeignClient动态代理生成源码

    年前的时候我发布两篇关于nacos源码的文章,一篇是聊一聊nacos是如何进行服务注册的,另一篇是一文带你看懂nacos是如何整合springcloud -- 注册中心篇.今天就继续接着剖析Sprin ...