TLS协议详解

TLS协议

一,TLS协议的组成

image

TLS协议架构模块分为两层:TLS记录协议,TLS握手协议

TLS记录协议: 是所有子协议的基层,规定了TLS收发数据的基本单位。所有子协议都需要通过记录协议发出,多个记录数据可以在一个TCP中发送。主要负责使用对称密码对消息进行加密。

TLS握手协议:

  • 握手协议:客户端和服务端在握手过程中协商 TLS版本号,随机数,密码套件,交换证书,最终获取会话密钥。
  • 密码规格变更协议:发送一个通知,告知对方后续的通信采用加密保护。
  • 警告协议:向对方发出警告,类似于http中的状态码。不支持旧版本,证书异常都会发送警报,另一方收到警报后可以进行相应的处理
  • 应用数据协议:将TLS承载的应用数据传达给通信对象

二,TLS的握手过程

image

上图是TLS握手的一个简易流程,每一个框就是一个 TLS Record(记录),多个Record合并成一个TCP来进行发送,可以看到整个TLS握手只需要2次消息往返即2RTT就能完成 ( TLS 1.2是2RTT,TLS 1.3可以做到 1RTT甚至0RTT )

接下来我们来结合wireshark抓包来详细介绍每一步的流程:

1,ClientHello

image
首先客户端先向服务端发起握手请求,在这个请求过程中client会携带以下参数

  • TLS 版本: 确定使用1.2还是1.3 但是这个地方固定是1.2。之后我们会在1.2与1.3的兼容性中聊到
  • Client提供的随机数: 用于后续生成会话密钥
  • Cipher Suites: 可用密码套件列表,供服务端选择
  • 会话ID(可忽略): 可用于之后TLS1.3的优化 —— 会话缓存
  • 可用压缩方式
密码套件

客户端和服务端在使用TLS建立连接时需要选择一组恰当的加密算法来实现安全通信,这些算法的组合就被称为 密码套件
如图中的密码套件那一行:TLS_ECDHE_RSA_WITH_AES_128-CBC-SHA 他的意思是

  • 握手时使用ECDHE算法进行密钥交换
  • 用RSA签名和身份认证
  • 握手后的通信使用 AES对称算法,密钥长度 128 位
  • 分组模式为 CBC
  • 摘要算法为 SHA 用于消息认证和产生随机数

2,ServerHello

服务端接收到客户端的握手请求,会回复客户端同时 发送 ServerHello,ServerHello会根据之前的ClientHello的参数来做如下操作:

  • **确认 TLS版本 **
  • 服务器提供的随机数
  • 选择的密码套件

3,Server Certificate

数字证书 与 CA

① CA证书:
我们知道 在 https中 加密采用了非对称加密,通过私钥加密,公钥解密。私钥由双方生成并维护。但是公钥不能任意生成,公钥涉及到一个公钥信任问题,谁都能发布公钥的话,黑客就可以伪造公钥来进行攻击。所以说公钥得由一个公认可信的第三方生成,让他作为信任的起点,递归的终点,构建信任链,这个第三方就是 CA(证书认证机构)

② CA证书链:
CA可以签发三种证书,他们的区别在于可信程度,按照可信程度从高到低来排序即为:EV, OV, DV
CA如果想证明自己,可以找上级CA为自己签发证书,不断向上直到 Root CA。Root CA会给自己签发自签名证书或者根证书,这个证书是必须相信的。

如下图所示即为数字证书CA的信任链
image

③ 证书弱点:
证书的签发可能失误或者被欺骗,签发了错误的证书,这个时候可以通过 CRL(证书吊销列表) 和 OCSP(在线证书状态协议)来及时对问题证书进行废止

服务端会将自己的证书链发送给客户端,交给客户端进行验证。值得注意的不是只发送一个证书,前文有说到 二级CA的证明需要一级CA的证明,验证二级证书的签名需要一级证书的公钥来进行解密,所以需要返回一整个证书链(无需携带根证书,用户浏览器自带了根证书)

4,Server Key Exchange

以 ECDHE算法为例,服务端生成一个 公钥 名为Server Params,用来实现密钥交换算法,再用私钥进行签名认证

Handshake Protocol: Server Key ExchangeEC Diffie-Hellman Server ParamsCurve Type: named_curve (0x03)Named Curve: x25519 (0x001d)Pubkey: 3b39deaf00217894e...Signature Algorithm: rsa_pkcs1_sha512 (0x0601)Signature: 37141adac38ea4...

5,Client Key Exchange

客户端首先会先对证书链进行验证,再根据服务端所选的算法以及Server Params来生成对应的Client Params返回给服务端

Handshake Protocol: Client Key ExchangeEC Diffie-Hellman Client ParamsPubkey: 8c674d0e08dc27b5eaa…

此时服务端和客户端拥有了 Client Params,Server Params,Client Random,Server Random,服务端会先使用Params用ECDHE算法生成一个Pre-Master,再用 Random + Pre-Master 生成主密钥 Master Secret。

master_secret = PRF(pre_master_secret, "master secret",ClientHello.random + ServerHello.random)// 之所以需要使用三个随机数来生成主密钥,是因为TLS的设计者并不信任服务端和客户端生成的随机数的可靠性。所以将三个不可靠的随机数混合起来来提升随机数的随机程度。

有了主密钥后并不会直接进行使用,而是通过PRF算法扩展出更多的派送会话密钥,来用作每次会话的独立密钥。这样即使主密钥泄露已传输的数据仍然安全,因为每次会话的密钥是独立的具备前向安全性。

6,Change Chiper Spec & Finished

通信转换为使用会话密钥 + 对称算法进行加密通信,并且握手结束。
由于使用的是ECDHE,客户端可以无需等待服务端返回 Finished就直接发出HTTP报文,省去等待一个消息返回的时间浪费,这个叫做
TLS False Start

图示总结(以ECDHE握手为例)

三,TLS 1.3

TLS 1.3 相比于 TLS 1.2有了以下几项巨大的提示:兼容,性能,安全

1,兼容性

在TLS 1.2时期,版本号是记录在Version字段的,即Version:TLS 1.2(0x0303)。我们可能理所应当的认为TLS 1.3就是Version:TLS 1.3(0X0304)。但是这样肯定不行,这样会导致大量只认老协议的代理服务器,网关都无法处理请求,导致握手失败。

如果要进行区分1.2 和 1.3就要通过新引入的协议 扩展协议,在当前的记录后添加一列拓展字段,老版本因为不认识则直接舍弃,新版本则可以对其进行识别处理,这便实现了向后兼容

所以 TLS 1.3 还是保留 Version:TLS 1.2(0x0303),只不过在 扩展协议 中新加了有一个 #supported_version扩展,在这个扩展中标记了TLS的版本号

Handshake Protocol: Client HelloVersion: TLS 1.2 (0x0303)Extension: supported_versions (len=11)Supported Version: TLS 1.3 (0x0304)Supported Version: TLS 1.2 (0x0303)

2,性能提升

TLS 1.3 相比于 TLS 1.2最大性能提升就是 原先TLS1.2握手需要 2RTT,现在TLS1.3握手只需 1RTT,性能整整提升了一倍。
image
优化的点如下:
1,TLS 1.3舍弃了之前的繁琐的协商方式,在第一次Client Hello时 通过扩展组就将签名算法,客户端公钥参数(Client Params)等等内容全部提供了服务端。同时服务端会在Server Hello时就携带好各种参数以及ChangeCipherSpec。

通过这两点 成功将握手的报文发送提升至 1RTT

3,安全性(待补充)

废弃了一些分组和加密算法,由于没具体学加密算法,学了之后再补充

密码套件大大减少,得益于密码套件的减少,在Client Hello阶段可以直接生成公钥参数以及曲线
image

四, TLS 1.3 握手过程

1,Client Hello

Handshake Protocol: Client HelloVersion: TLS 1.2 (0x0303)Random: cebeb6c05403654d66c2329…Cipher Suites (18 suites)Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)Extension: supported_versions (len=9)Supported Version: TLS 1.3 (0x0304)Supported Version: TLS 1.2 (0x0303)Extension: supported_groups (len=14)Supported Groups (6 groups)Supported Group: x25519 (0x001d)Supported Group: secp256r1 (0x0017)Extension: key_share (len=107)Key Share extensionClient Key Share Length: 105Key Share Entry: Group: x25519Key Share Entry: Group: secp256r1

TLS 1.3与TLS 1.2相比而言,新增了三个拓展项

  • supported_version:这个我们之前有提到,TLS 1.3需要使用该拓展项来进行版本区分
  • supported_group:支持的曲线
  • key_share:曲线对应的参数

可以看到相比于1.2,1.3再hello的时候就将自身支持的参数发送给了服务端

2,Server Hello

收到客户端的消息后,此时服务端就拥有了 Client Random 和 Server Random 、Client Params 和 Server Params,可以直接通过ECDHE算出 Pre-Master。

此时通过 Certificate Verify一个安全增强措施,用私钥将曲线,套件,参数等数据进行数字签名,强化了身份认证和防篡改。

可以发现 生成会话密钥以及进入加密通信的时间要比TLS 1.2更加的早。TLS 1.2还需要进行一次繁琐的 Key Exchange,而1.3在两次Hello中就已经完成了Key的交换

五,HTTPS的优化

HTTPS在HTTP握手的基础上加上了一个TLS握手,所以他的连接速度肯定也会有所下降,有时甚至会比HTTP慢上几秒(远古时期),这下子 HTTPS的已经刻板印象的变成 “Slow” 了。那本章我们来分析 HTTPS究竟慢在哪以及如何优化。

首先HTTPS的加密分为了两部分 TLS握手前的非对称加密TLS握手后的对称加密
**对称加密:**目前TLS支持的对称加密算法性能很好 再加上硬件优化,这块的性能损耗很小可以忽略不计

那我们就可以把 [慢] 聚集于 TLS握手期间,我们可以将销毁总结为以下几点:

  • 握手所需的额外报文传输
  • 验证证书时 需要访问 CA 获取 CRL或OCSP
  • 非对称加密处理 Pre-Master
  • 产生用于密钥交换的临时公私钥对

image

1,加解密优化:

SSL加速卡 or SSL加速服务器: 使用专门的加速卡来分担CPU的计算压力 或者 使用 SSL加速服务器集群 [卸载] TLS握手时的加解密计算,提升加解密的速度

协议优化:
选择更快更好的密码套件,会使加解密,密钥交换过程中更加快速 例如:
性能更高的曲线:x25519
对称加密算法:AES_128 会比 AES_256 更好一点
密钥交换协议:ECDHE运算更快,安全性高,支持False Start,将握手消息往返由 2-RTT减少至 1-RTT

这些都可以在nginx的配置文件中进行设置 例如:ssl_ciphers、ssl_ecdh_curve

ssl_ciphers   TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:EECDH+CHACHA20;
ssl_ecdh_curve              X25519:P-256;

2,证书优化:

在TLS 1.2中我们有说到,服务器需要将自己的证书链发送给客户端。那这里 证书的传输 以及 证书的验证 就是性能损耗的关键点。

证书的传输: 在传输的方面,我们需要减小证书的大小,这样可以节约带宽以及减小计算量。那我们可以选择ECDHE椭圆曲线的证书,ECDHE证书(224位)相比于RSA证书(2048位)小了很多。

证书的优化: 证书在验证过程中不仅要面对繁琐的解密,如果证书撤销,客户端还需要访问CA,下载CRL或者OSCP的数据,产生DNS查询,连接建立,收发数据等一系列网络通信。

那我们可以选择将 CRL和OSCP保存起来,这样就无需进行额外的网络查询。

  • **CRL(不推荐):**CRL是定期发布的,这样会存在时间窗口的安全隐患,而且CRL中存放的是所有被吊销的证书,这个列表只会不断变大,动辄 几MB 保存CRL是不可取的
  • **OCSP Stapling:**这是OSCP的一个新补丁,原先的OCSP是在线证书状态协议,他也需要查询CA然后获取证书状态。但是OCSP Stapling 我们可以让服务器预先访问CA获取OCSP的响应,在握手的过程中将证书和OCSP查询的状态在握手时一起返回给客户端,这样就无需进行额外的查询

3,会话复用

在客户端和服务器首次连接后会各自保存一个Session ID,并且为当前会话生成一个主密钥Master。那我们能不能将主密钥Master生成这个过程跳过了,这样就跳过了证书验证和密钥交换。答案是 有的,兄弟有的

缓存SessionID(1RTT): 在第一次连接后,服务器内存保存SessionId以及当前会话的主密钥,当客户端再次连接时发送一个ID过来,就从缓存中寻找,如果找到对应的主密钥则恢复会话,并且跳过证书验证和密钥交换。

Session Ticket(1RTT): 第一种是由服务器缓存会话ID,但是对于千万级连接的服务器,这样的内存开销是十分大的。所以这个时候我们可以做一个缓存对象转换.
1,第一次访问时服务端,使用有效期的ticket密钥对Session签发的Ticket,客户端接收到后缓存Ticket。
2,客户端下一次建立连接时使用拓展 session_ticket发送 Ticket。
3,服务端获取Ticket,并进行解密校验是否有效,是否超时。如果正常则恢复会话并进行加密通信。

预共享密钥(0RTT): 在TLS1.3下,可以通过该方法达到 0RTT,在Ticket的基础上同时携带上应用数据(Early Data),这种方式叫做Pre-shared Key,检简称**PSK **
image

这样可以免去服务器确认的步骤,实现0-RTT。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/75772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ollama更新升级及警告解决

1. 概述 在大模型业务处理中,需要用到gemma3 和 qwen2.5-VL,当前服务器的ollama版本 0.3.11,无法满足要求,需要更新升级。 2. 实施过程 参考官网升级要求: curl -fsSL https://ollama.com/install.sh | sh 不知道…

ubuntu 配置固定ip

在装服务器系统的时候,DHCP自动获取ip时,路由可能会重新分配ip,为避免产生影响,可以关闭DHCP将主机设置为静态ip。 系统环境 Ubuntu 22.04-Desktop 配置方式 一、如果是装的Ubuntu图形化(就是可以用鼠标操作点击应用…

套接字编程函数recv和send ,以及设置reuseaddress

recv就是去套接字读缓冲区读数据 阻塞模式下:读缓冲区没数据那就阻塞等待,若等待被打断返回-1设置errno为EINTR 非阻塞模式下:读缓冲区没数据那就返回-1,设置errno为EAGAIN或EWOULDBLOCK。 若连接断开返回0,读取成功…

《C++后端开发最全面试题-从入门到Offer》目录

当今科技行业对C++开发者的需求持续高涨,从金融科技到游戏开发,从嵌入式系统到高性能计算,C++凭借其卓越的性能和灵活性始终占据着关键地位。然而,成为一名优秀的C++工程师并非易事,不仅需要扎实的语言基础,还要掌握现代C++特性、设计模式、性能优化技巧以及各种工业级开…

设计模式简述(十)责任链模式

责任链模式 描述基本使用使用 描述 如果一个请求要经过多个类似或相关处理器的处理。 可以考虑将这些处理器添加到一个链上,让请求逐个经过这些处理器进行处理。 通常,在一个业务场景下会对整个责任链进行初始化,确定这个链上有哪些Handler…

初识数据结构——Java集合框架解析:List与ArrayList的完美结合

📚 Java集合框架解析:List与ArrayList的完美结合 🌟 前言:为什么我们需要List和ArrayList? 在日常开发中,我们经常需要处理一组数据。想象一下,如果你要管理一个班级的学生名单,或…

ReFormX:现代化的 React 表单解决方案 - 深度解析与最佳实践

ReFormX文档 表单开发一直是前端工作中最繁琐却又最常见的任务之一。从简单的登录表单到复杂的多步骤配置页面,开发者往往需要编写大量重复代码,处理繁琐的状态管理、数据验证和联动逻辑。ReFormX 应运而生,它不仅是一个表单组件库&#xff…

WinForm真入门(9)——RichTextBox控件详解

WinForm中RichTextBox控件详解:从基础到高级应用 上一文中笔者重点介绍了TextBox控件的详细用法,忘记的 请点击WinForm真入门(8)——TextBox控件详解,那么本文中的RichTextBox与TextBox有什么区别吗,光看名字的话,多了…

Draw.io 全面解析与竞品分析:图表绘制工具的深度对比

目录 一、Draw.io 全面介绍 1. 产品概述 2. 核心功能特点 3. 用户体验 4. 商业模式 二、市场竞品分析 1. 主要竞品概览 2. 深度功能对比 3. 价格策略对比 4. 技术架构对比 三、用户场景与选择建议 1. 不同场景下的工具推荐 2. 未来发展趋势 四、结论 diagrams.net…

kafka分区策略详解

Kafka 分区策略详解 Kafka 的分区策略决定了消息在生产者端如何分配到不同分区,以及在消费者端如何动态分配分区以实现负载均衡。以下是 Kafka 核心分区策略及其适用场景的详细解析: 1、生产者分区策略 生产者负责将消息发送到 Topic 的特定分区&#…

C++ STL 详解 ——list 的深度解析与实践指南

在 C 的标准模板库(STL)中,list作为一种重要的序列式容器,以其独特的双向链表结构和丰富的操作功能,在许多编程场景下发挥着关键作用。深入理解list的特性与使用方法,能帮助开发者编写出更高效、灵活的代码…

GenerationMixin概述

类 类名简单说明GenerateDecoderOnlyOutput继承自 ModelOutput,适用于非束搜索方法的解码器-only模型输出类。GenerateEncoderDecoderOutput继承自 ModelOutput,适用于非束搜索方法的编码器-解码器模型输出类。GenerateBeamDecoderOnlyOutput继承自 Mod…

【备赛】蓝桥杯嵌入式实现led闪烁

原理 由于蓝桥杯的板子带有锁存器,并且与lcd屏幕有冲突,所以这个就成了考点。 主要就是用定时器来实现,同时也要兼顾lcd的冲突。 一、处理LCD函数 首先来解决与lcd屏幕冲突的问题,把我们所有用到的lcd函数改装一下。 以下是基…

C++ 并发性能优化实战:提升多线程应用的效率与稳定性

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,获得2024年博客之星荣誉证书,高级开发工程师,数学专业,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发技术&#xff0c…

Python----计算机视觉处理(Opencv:道路检测之车道线拟合)

完整版: Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示) 一、获取左右车道线的原始位置 导入模块 import cv2 import numpy as np from matplot…

优选算法的妙思之流:分治——归并专题

专栏:算法的魔法世界 个人主页:手握风云 目录 一、归并排序 二、例题讲解 2.1. 排序数组 2.2. 交易逆序对的总数 2.3. 计算右侧小于当前元素的个数 2.4. 翻转对 一、归并排序 归并排序也是采用了分治的思想,将数组划分为多个长度为1的子…

C语言查漏补缺:基础篇

1.原理 C语言是一门编译型计算机语言,要编写C代码,C源代码文本文件本身无法直接执行,必须通过编译器翻译和链接器的链接,生成二进制的可执行文件,然后才能执行。这里的二进制的可执行文件就是我们最终要形成的可执行程…

TPS入门DAY02 服务器篇

1.创建空白插件 2.导入在线子系统以及在线steam子系统库 MultiplayerSessions.uplugin MultiplayerSessions.Build.cs 3.创建游戏实例以及初始化会话创建流程 创建会话需要的函数,委托,委托绑定的回调,在线子系统接口绑定某一个委托的控制其…

产品经理课程

原型工具 一、土耳其机器人 这个说法来源于 1770 年出现的一个骗局,一个叫沃尔夫冈冯肯佩伦(Wolfgang von Kempelen)的人为了取悦奥地利女皇玛丽娅特蕾莎(Maria Theresia),“制造”了一个会下国际象棋的机…

nginx中的limit_req 和 limit_conn

在 Nginx 中,limit_req 和 limit_conn 是两个用于限制客户端请求的指令,它们分别用于限制请求速率和并发连接数。 limit_req limit_req 用于限制请求速率,防止客户端发送过多请求影响服务器性能。它通过 limit_req_zone 指令定义一个共享内存…