背景介绍

近期收到同事反馈,在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. 《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)

    1.简介 页面对象模型(Page Object Model)在Selenium Webdriver自动化测试中使用非常流行和受欢迎,作为自动化测试工程师应该至少听说过POM这个概念.本篇介绍POM的简 ...

  2. 关于python中selenium一些知识点

    selenium几种元素操纵方法 切换iframe层 #切换至xx iframe层 driver.switch_to.frame("name and id") # 切回主HTML层 ...

  3. [AcWing 800] 数组元素的目标和

    点击查看代码 #include<iostream> using namespace std; const int N = 1e5 + 10; int a[N], b[N]; int mai ...

  4. react实战系列 —— 我的仪表盘(bizcharts、antd、moment)

    其他章节请看: react实战 系列 My Dashboard 上一篇我们在 spug 项目中模仿"任务计划"模块实现一个类似的一级导航页面("My任务计划") ...

  5. ucore lab6 调度管理机制 学习笔记

    这节虽叫调度管理机制,整篇下来主要就讲了几个调度算法.兴许是考虑到LAB5难,LAB6就仁慈了一把,难度大跳水.平常讲两节原理做一个实验,这次就上了一节原理.权当大战后的小憩吧. schedule函数 ...

  6. 没错,华为开始对IoT下手了!

    最近,有很多粉丝在后台私信 想知道目前最热的技术是什么? 小编觉得,5G时代到来 物联网技术将迎来快速的发展 加上目前,国内物联网人才短缺 每年人才缺口达百万 IoT物联网将成为最热门的技术 最近,小 ...

  7. kernel heap bypass smep,smap && 劫持modprobe_path

    kernel heap bypass smep,smap && 劫持modprobe_path exp1 smep:smep即用户数据不可执行,当 CPU 处于 ring0 模式时,执 ...

  8. WTF表单验证

    WTF表单验证可分为3个步骤: ①导入wtf扩展提供的表单验证器.(from wtforms.validators import DataRequired,EqualTo) ②定义表单类 # 定义表单 ...

  9. Python Selenium库

    Selenium库 自动化测试工具,支持多种游览器 爬虫中主要用来解决JavaScript渲染的问题 安装Selenium pip3 install selenium 安装游览器驱动 下载驱动地址:h ...

  10. CabloyJS全栈开发之旅(1):NodeJS后端编译打包全攻略

    背景 毋庸置疑,NodeJS全栈开发包括NodeJS在前端的应用,也包括NodeJS在后端的应用.CabloyJS前端采用Vue+Framework7,采用Webpack进行打包.CabloyJS后端 ...