【学习笔记】TLS/SSL握手
前言:本篇将介绍TLS握手的实际握手过程,TLS握手创建了Client和Server之间“被保护的通道”,2个单向通道用来保护批量数据的传输(通过Confidentiality、Integrity和Authentication),一个通道是从Client到Server,另一个是从Server到Client。本篇将介绍最基础的握手 - 即握手采用的是RSA密钥交换,并通过追条记录(Record)的形式来阐述该过程。

在整个握手的过程中,Client和Server会交换并计算特定的值。上图两侧的框是双方所拥有的信息。开始时,Server已经拥有了证书、公钥和私钥,
1、Handshake:Client Hello
第一条Record是Client Hello,里面包含5个部分
- Version
- 包含了Client所支持的TLS/SSL的最高版本
- Random Number - 32 bytes / 256 bits
- 前4个字节编码时间戳(防止两个拥有相同随机数的不同的Client Hello相互发送信息)
- Session ID - 8 bytes / 32 bits
- 00000...本篇中Client Hello的初始会话ID都是0
- Cipher Suites
- Client会发送它所支持的密码套件的列表,Server会从中挑选
- Extensions
- 如果有扩展的话会包含在握手中,本篇不包含扩展
2、Handshake:Server Hello
收到Client Hello后,Server会发出Server Hello,和Client Hello一样,包含5部分
- Version
- 包含了Server所支持的TLS/SSL的最高版本
- Random Number - 32 bytes / 256 bits
- 前4个字节编码时间戳
- Session ID - 8 bytes / 32 bits
- Server生成的用于识别后续会话密钥的值
- Cipher Suites
- Server(从Client发送的列表中)挑选的密码套件
- Extensions
- 如果有扩展的话会包含在握手中,本篇不包含扩展
在Client Hello和Server Hello之后,Client和Server都获得了额外的信息
- 两者都知道了互相支持的TLS版本。如果Client发送说它支持TLS 1.3,Server返回说它支持TLS 1.2,这就表明两者互相支持的最高的版本是TLS 1.2,两者将用TLS 1.2协议进行握手
- 两者都知道了互相的随机数(Client Random、Server Random)
- 两者也知道未来会用来参考本次会话的ID
- 互相同意的用来保护这次TLS会话的密码套件
3、Handshake:Certificate
这条记录包含了Server证书和完整的证书链,Client会收到证书和公钥。Client收到证书后会问自己2个问题:证书是否合法?(用CA公钥进行的签名可以验证其合法性,在此处Client拥有了其所需要的东西来验证该签名);Server是否是该证书的真正拥有者?(验证Server拥有与证书匹配的私钥,会由Key Exchange Record所验证)
4、Handshake:Server Hello Done
这是一条空的Record,表明Server此时没有更多信息进行发送;然而,握手的其他变体可能会要求Server发送更多信息。
5、Handshake:Client Key Exchange
Client Key Exchange有2个主要目的
- 创建相互的密钥材料(例如,SEED Value种子值,Client和Server两者都用来生成会话密钥)
- 证明Server确实是该证书的拥有者
2个目的都将由特殊的值所达成,即 Pre Master Secret,预主密钥。上图中用红色虚线框描述,表明该值是加密发送的
- Pre Master Secret 的生成
- Client生成 Pre-Master-Secret (包含48个字节)
- 2 bytes - TLS/SSL Version
- 46 bytes - Random(随机生成的)
- 之后,Pre-Master-Secret 会被Server的公钥进行加密(Client已经有了,因为前面的Record中Server已经发送了)
- Pre-Master-Secret 被加密后进行在线传输,唯一能提取该加密信息的,是拥有与之相匹配的私钥的一方,即有对应私钥的Server
- 现在,两者就都拥有了 Pre-Master-Secret
- Client生成 Pre-Master-Secret (包含48个字节)
- Pre Master Secret 的生效(在本例中,该值被用作种子值,来生成TLS会话密钥)
- 双方都有了匹配的SEED Value
- 种子值被用来生成会话密钥
- 预主密钥被用来生成主密钥(Master Secret)[ 将其他值与PreMasterSecret相结合,这些值是“master secret”文字字符串(包含在RFC里了)、Client Random和Server Random,这4个值会相互结合来生成Master Secret ]
- 主密钥被用来生成会话密钥 [ 将其他值与Master Secret相结合,这些值是“Key expansion”文字字符串、Client Random和Server Random,这4个值会相互结合来生成会话密钥 ]
- 至少生成4个会话密钥(2套不同的密钥):
- 保护Client发送信息的Client Encryption Key和Client HMAC Key
- 保护Server发送信息的Server Encryption Key和Server HMAC Key
- 至少生成4个会话密钥(2套不同的密钥):

- 特定加密协议需要 I.V. 即 Initializational Vector,初始化向量,这是(PRF)计算必要的I.V.的步骤
- 计算涉及PRF - Pseudo Random Function,伪随机数函数
- 生成任意长度的摘要的哈希算法
- 双方都有了匹配的SEED Value
到此,Client和Server双方都有了完全相同的会话密钥;但是,Client或Server并不知道另一方拥有相同的密钥。
因而,余下的握手将给双方证明:另一方拥有正确的会话密钥。
6、Change Cipher Spec(不是Handshake Record)
该记录表明Client已做好安全通话的一切准备(意味着它可以计算出会话密钥了)。我们可以阅读该记录,Client在说,它做好准备去更改由Client和Server所指定的密码。
7、Handshake:Finished
- 向Server证明:Client有正确的会话密钥
- 这会由特定的值(Encrypted Verification)来完成,过程如下
- Client计算出之前所有握手记录(5个)的哈希,这5个记录会一起被哈希,生成Handshake Hash
- 然后,Handshake Hash会与其他值(“client finish”字符串和Master Secret)相结合来生成验证数据(Verification Data)
- 最终,验证数据会被Client Session Keys加密,生成加密验证
- Server用自己的Client会话密钥副本进行验证
- 验证Client和Server“看见”相同的握手记录
-

- 理论上,Server也看见了之前5个握手记录(即Handshake Hash),“client finished”字符串,同时Server也有Mater Secret,这表明Server能合并得到相同的Verification Data;之后,Server收到加密验证后,用Client Session Key副本去进行解密,如果得到的结果和Server自己合并得到的验证数据相同,这就向Server表明,Client拥有相同的会话密钥。如果有人在Client发送出Client Hello后,Server接受到之前,进行篡改,两边的Verification Data会不匹配
8、Change Cipher Spec(不是Handshake Record)
该记录表明Server已做好安全通话的一切准备(意味着它可以计算出会话密钥了)
9、Handshake:Finished
- 向Client证明:Server有正确的会话密钥
- 类似的过程
- Client计算出之前所有握手记录(6个)的哈希,得到Handshake Hash
- Handshake Hash会与其他值(“server finish”字符串和Master Secret)相结合来生成验证数据(Verification Data)
- 验证数据会被Server Session Keys加密,生成加密验证
- Client用自己的Server会话密钥副本进行验证
-

在此刻的握手中,Client和Server都计算出相同的会话密钥,并且相互向对方证明自己有正确的会话密钥。这意味着两者可以开始分享批量数据了,并用协商好的会话密钥保护该数据。
以上就是TLS握手(我们阐述的是basic handshake)的全部过程
需要知道的是,TLS握手发生在我们每次访问HTTPS网站的时候,或者每次我们链接SSL VPN(Virtual Private Network)的时候
参考文献
1、网站:https://www.practicalnetworking.net/:practical TLS
相关文章:
【学习笔记】TLS/SSL握手
前言:本篇将介绍TLS握手的实际握手过程,TLS握手创建了Client和Server之间“被保护的通道”,2个单向通道用来保护批量数据的传输(通过Confidentiality、Integrity和Authentication),一个通道是从Client到Ser…...
ESP32-TFT_eSPI.h文件的使用心得(包含画图相关函数)
目录 前言 环境:arduino 芯片:ESP32 一、Arduino中的使用 #include <TFT_eSPI.h> TFT_eSPI tft TFT_eSPI();tft.init();//初始化tft.setRotation(0); //屏幕旋转方向tft.fillScreen(TFT_BLACK);//底色tft.setTextSize(2); …...
vite分目录打包以及去掉默认的.gz 文件
1.vite打包情况介绍: 1.1vite在不进行任何配置的情况下,会将除开public的所有引用到资源打包编译添加哈希值至assets文件夹中(非引用文件以及行内样式图片未被打包编译资源会被treeSharp直接忽略不打包), 1.2w…...
Tensorflow 2.0 cnn训练cifar10 准确率只有0.1 [已解决]
cifar10 准确率只有0.1 问题描述踩坑解决办法 问题描述 如果你看的是北京大学曹健老师的tensorflow2.0,你在class5的部分可能会遇见这个问题 import matplotlib.pyplot as plt import tensorflow as tf from tensorflow.keras.layers import Dense, Dropout,MaxPooling2D,Fla…...
828华为云征文 | 在华为云上通过Docker容器部署Elasticsearch并进行性能评测
目录 前言 1. 华为云X实例介绍及优势 1.1 柔性算力 1.2 vCPU和内存的灵活配比 1.3 成本效益与性能 2. 安装并运行 Docker 2.1 修改仓库配置文件 2.2 安装 Docker 2.3 启动 Docker 3. 使用Docker部署Elasticsearch 3.1 拉取Elasticsearch镜像 3.2 启动Elasticsearch…...
生态位模型降重创新专题系列【2025
本内容旨在丰富最大熵模型的分析内容,并针对目前文章存在的问题:(1)分析内容单一,重复度高和查重率高,(2)建模流程过于简单,结果可信度评估方法过于单一等;推…...
LeetCode234. 回文链表(2024秋季每日一题 26)
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true 示例 2: 输入:hea…...
项目(石头剪刀布游戏双循环)
while (true) { #region 猜拳游戏主题逻辑 // 定义猜拳次数 int count 3; //定义用户赢得次数 int winCount 0;// 初始值为零表示用户一次没饿赢 int sysCou…...
Linux 进程3
进程地址空间 CPU读取数据都需要地址,在计算机中所有东西都是一种数据,包括我们的进程。 这是一个进程空间示意图,操作系统通过task_struct结构体链表来管理每一个进程,结构体里面有一个指针指向操作系统为进程开辟的一段空间&am…...
R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析
随机森林作为一种集成学习方法,在处理复杂数据分析任务中特别是遥感数据分析中表现出色。通过构建大量的决策树并引入随机性,随机森林在降低模型方差和过拟合风险方面具有显著优势。在训练过程中,使用Bootstrap抽样生成不同的训练集ÿ…...
shell linux cut 切割字符串
shell linux 切割字符串 在Shell脚本中,可以使用内置的cut命令来切割字符串。cut命令主要有三个选项 -c、-f和-d,分别表示按字符、按字段和指定分隔符来切割字符串。 按字符切割: echo "Hello World" | cut -c 1-5 # 输出&#…...
golang学习笔记31——golang 怎么实现枚举
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
fastadmin本地安装插件提示”请从官网渠道下载插件压缩包(code:2)(code:1)“
这个问题主要是在fastadmin中为了保证安全性,不让你进行本地的一个安装(离线安装) 解决办法就是去把相应的代码注释掉,把相应的权限开启。 具体步骤 1.在后台的application\config.php文件下; 将这个unknownsources的…...
STM32基础学习笔记-Timer定时器面试基础题5
第五章、TIMER 常见问题 1、基本概念:什么是定时器 ?作用 ?分类 ? 2、时基单元 ?组成 ?计数模式 ?溢出条件 ? 溢出时间计算 ? 3、systick原理 ?代码讲解 &…...
CSS06-元素显示模式、单行文字垂直居中
一、什么是元素显示模式 1-1、块级元素 1-2、行内元素 1-3、行内块元素 1-4、小结 二、元素显示模式转换 三、单行文字垂直居中 CSS 没有给我们提供文字垂直居中的代码,这里我们可以使用一个小技巧来实现。 解决方案: 让文字的行高等于盒子的高度,就可…...
【车联网安全】车端网络攻击及检测的框架/模型
参考标准: 《汽车数据安全管理若干规定(试行)》ISO/SAE 21434《道路车辆 网络安全工程》威胁分析和风险评估(TARA)ISO/DIS 24089R155法规的国标转换:《汽车整车信息安全技术要求》(UN R155&…...
58.【C语言】内存函数(memcpy函数)
目录 1.memcpy *简单使用 翻译: *模拟实现 注意事项: *例题 1.memcpy *简单使用 memcpy:memory copy cplusplus的介绍 点我跳转 翻译: 函数 memcpy void * memcpy ( void * destination, const void * source, size_t num ); 复制内存块 直接从source指向的位置复制num…...
rust一些通用编程的概念
rust一些通用编程的概念 官网文档数据类型 - Rust 程序设计语言 中文版 (rustwiki.org) 变量,数据类型,条件判断,循环 变量 rust中变量的可变性是值得注意的 例如: fn main(){let number 1;number 2;println!("the number is {}&quo…...
SpringBoot基础知识
谈一谈你对SpringBoot的理解,它有哪些特性(优点)? SpringBoot用来快速开发Spring应用的一个脚手架,其目的是用来简化新Spring应用的初始搭建以及开发过程。 优点: 简化配置:提供了很多内置的…...
ubuntu配置libtorch CPU版本
配置环境:Ubuntu 20.04Date:2024 / 08 1、下载最新版本的libtorch wget https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip unzip libtorch-shared-with-deps-latest.zip2、创建一个C工程文件夹,目…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
