TLS1.3握手流程以及参数详解

TLS1.3握手流程以及参数详解

TLS1.3总共有两层,分别是握手协议(handshake protocol)和记录协议(record protocol),握手协议在记录协议的上层,记录协议是一个分层协议。其中握手协议中还包括了警告协议(alert protocol)。本文将详细阐述握手协议,并且抓包分析。

我在一年前写了一篇介绍TLS1.3的文章,最近工作遇到了TLS1.3协议。重新复习了下。

这篇文章想详细的阐述交互过程,以及抓包分析参数的含义。

 

文章目录

  • TLS1.3概述
  • TLS1.3记录协议:
  • TLS1.3警告协议:
  • TLS1.3握手协议:
  • 分析ClinetHello:
  • 分析ServerHello:
  • client的认证部分:
  • 数据传输部分

TLS1.3概述

TLS1.3总共有两层,分别是握手协议(handshake protocol)和记录协议(record protocol),握手协议在记录协议的上层,记录协议是一个分层协议。其中握手协议中还包括了警告协议(alert protocol)。

TLS1.3概括如表格所示:

本文将详细阐述握手协议,并且抓包分析。

 

TLS1.3记录协议:

记录协议位于握手协议下层,发送方从高层接受任意长度的非空数据,对其进行合并或分块处理,然后利用带有辅助数据的认证加密AEAD(authenticated encryption with associated data)进行加密传输。

接收方接受数据后对其进行解密和验证,重组后再传送给高层用户。

 

TLS1.3警告协议:

目的是以简单的通知机制告知通信出现异常情况,警告消息通常会携带Close_notify异常,在连接关闭的时候报告错误,Alert_Level字段标识告警的严重程度,可取值Warning或者Fatal,严重程度为Fatal时会立即终止当前连接。

 

TLS1.3握手协议:

握手协议主要分为三个流程

  1. 密钥交换:选择TLS协议版本和加密的算法,并且协商算法所需的参数。这段是明文传输的
  2. 服务器参数:建立其他握手协议参数,例如是否需要认证客户端,支持何种应用层协议等。
  3. 认证:对服务器进行认证(包括可选的客户端认证)并且提供密钥确认和验证握手完整性功能。

这三个阶段完成后就可以进行应用层数据传输。

流程图如下所示:

注:+:上一消息的扩展消息;*:可选发送

{}:用握手层流密钥加密;[]:用流密钥加密

TLS1.3的交互过程分为1-RTT,RTT是时延往返的意思。RTT越小速度越快。

在TLS1.2里交互过程需要2-RTT,可见TLS1.3加快了交互的速度。

正常连接(1-RTT)流程如下:

第1步,客户端发送 ClientHello 消息,该消息主要包括客户端支持的协议版本、会话ID、密码套件、压缩算法、以及扩展消息(密钥共享、预共享密钥、预共享密钥模式);

第2步,服务端回复 ServerHello,包含选定的加密套件;发送证书给客户端;使用证书对应的私钥对握手消息签名,将结果发送给客户端;选用客户端提供的参数生成临时公钥,结合选定的参数计算出用于加密 HTTP 消息的共享密钥;服务端生成的临时公钥通过 KeyShare 消息发送给客户端;

第3步,客户端接收到 KeyShare 消息后,使用证书公钥进行签名验证,获取服务器端的临时公钥,生成会话所需要的共享密钥;

第4步,双方使用生成的共享密钥对消息加密传输,保证消息安全。

简单的说就是:

即4部分。ClientHello,SeverHello,Client认证,数据交互。

接下来分析这4个部分。

 

分析ClinetHello:


Handshake Type:ClientHello,表示握手消息类型,此处是ClientHello
Length:574,即长度为574
Version:TLS1.2(0x0303),表示版本号为1.2,TLS1.3中规定此处必须置为0x0303,即TLS1.2,起到向后兼容的作用。1.3版本用来协商版本号的部分在扩展当中,而之前的版本就在此处进行。
Random,随机数,是由安全随机数生成器生成的32个字节。
Session ID Length:会话ID的长度。
Session ID,会话ID,TLS 1.3之前的版本支持“会话恢复”功能,该功能已与1.3版本中的预共享密钥合并。为了兼容以前的版本,该字段必须是非空的,因此不提供TLS 1.3之前会话的客户端必须生成一个新的32字节值。该值不必是随机的,但应该是不可预测的,以避免实现固定在特定值,否则,必须将其设置为空。
Cipher Suites Length,即下面Cipher Suites的长度

Cipher Suites是密码套件,表示客户端提供可选择的加密方式,如图所示:

每个加密套件都包含,密钥交换,签名算法,加密算法,哈希算法。

Compression Methons (1 method)表示压缩方法,长度为1,内容为空

Exentisons扩展部分,是TLS1.3才开始使用,是TLS1.3的显著特征。每一个扩展都包含类型(type),长度(length)和数据(data)三个部分。

下面分析几个相对重要的扩展:

1key_share

key_share 是椭圆曲线类型对应的公钥,如图所示

此处包含两个KeyShareEntry,第一个是预留的空值,第二个是x25519曲线组,具体数据在KeyExchange字段中;每个KeyShareEntry都代表一组密钥交换参数。

2signature_algorithms

Signature_algorithms扩展是,客户端提供签名算法,让服务器选择

以第一个签名算法为例,ecdsa_secp256r1_sha256,使用sha256作为签名中的哈希,签名算法为ecdsa。

3psk_key_exchange_modes

psk_key_exchange_modes是psk密钥交互模式选择

此处的PSK模式为(EC)DHE下的PSK,客户端和服务器必须提供KeyShare

如果是仅PSK模式,则服务器不需要提供KeyShare。

4)pre_shared_key

psk是预共享密钥认证机制,相当于session ticket再加一些检验的东西

Identity中包含的是客户端愿意进行协商的服务器身份列表

PSK binder表示已经构建当前PSK与当前握手之间的绑定。
 

分析ServerHello:

发现和ClientHello类似。

CkientHello提供加密方式的选择,而ServerHello实质是在Client提供的多种加密中选定加密的方式

client的认证部分:

待到client认证完成,发送给服务端,至此建立连接,可以发送数据。

数据传输部分

可见数据经过TLS1.3加密,进行传输。


转载请注明:“转自绿盟科技博客”: 原文链接http://blog.nsfocus.net/tls1-3protocol/

### 使用Ollama构建本地知识库 #### 准备工作 为了成功搭建基于Ollama的本地知识库,需先完成必要的环境配置和资源准备工作[^1]。这包括但不限于安装Python解释器、pip包管理工具以及虚拟环境的支持。 #### 安装依赖项 通过命令行执行如下操作来设置项目所需的软件包: ```bash pip install ollama langchain rag ``` 上述指令会下载并安装`ollama`, `langchain` 和 `rag`三个主要组件,它们分别用于处理模型加载、链式调用逻辑实现和服务端API交互。 #### 配置Ollama服务 启动前要确保已正确设置了Ollama的服务地址与认证令牌,在代码中可以通过环境变量的形式传入这些参数: ```python import os os.environ["OLLAMA_API_KEY"] = "your_api_key_here" os.environ["OLLAMA_BASE_URL"] = "http://localhost:8000/api/v1" ``` 此部分设定对于后续连接至自托管的大规模预训练语言模型至关重要。 #### 加载大型语言模型 借助于LangChain框架可以简化LLM实例化过程,下面是一段简单的例子展示如何初始化一个特定版本的语言模型: ```python from langchain import LangChain model_name = "big-science/bloom-560m" # 可替换为其他支持型号 lc_model = LangChain.load(model=model_name, device="cuda") # 或者 'cpu' 如果GPU不可用 ``` 这段脚本实现了指定名称下的大规模预训练语言模型加载,并指定了计算设备类型(CPU/GPU),从而提高了灵活性和性能表现。 #### 构建检索增强生成(Retrieval-Augmented Generation,RAG) 最后一步是集成RAG机制到整个系统架构之中,使得查询请求不仅限于单纯依靠LM本身的知识范围,而是能动态地从外部数据源获取最新信息作为补充材料: ```python from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration tokenizer = RagTokenizer.from_pretrained("facebook/rag-token-nq") retriever = RagRetriever.from_pretrained( "facebook/dpr-question_encoder-single-nq-base", index_name="exact", use_dummy_dataset=True ) generator = RagSequenceForGeneration.from_pretrained("facebook/rag-sequence-nq") def generate_answer(question): inputs = tokenizer([question], return_tensors='pt') retrieved_docs_scores = retriever(**inputs) generated_ids = generator.generate(context_input_ids=retrieved_docs_scores.context_input_ids, context_attention_mask=retrieved_docs_scores.context_attention_mask) answer = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] return answer ``` 这里定义了一个名为`generate_answer()`的功能函数,它接受一个问题字符串输入并通过融合内部存储或数据库中的文档片段来形成最终的回答输出。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值