TLS1.3协议详解及其抓包分析

rfc8446是关于TLS1.3 协议的标准


TLS1.3的流程

在这里插入图片描述

在这里插入图片描述

注:

+:上一消息的扩展消息
*:可选发送
{}:用握手层流密钥加密
[]:用流密钥加密

这张彩图也不错
在这里插入图片描述

client hello

client hello的格式如下所示:

uint16 ProtocolVersion;
opaque Random[32];

uint8 CipherSuite[2];    /* Cryptographic suite selector */

struct {
      ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
      Random random;
      opaque legacy_session_id<0..32>;
      CipherSuite cipher_suites<2..2^16-2>;
      opaque legacy_compression_methods<1..2^8-1>;
      Extension extensions<8..2^16-1>;
} ClientHello;

通过wireshark,抓取到了连接测试网站1的client hello包,如图1所示,后续分析将和图1对照分析。

TLS1.3 client hello

图1 client hello wireshark 抓包

legacy versionsupported_versions
在TLS1.3之前的版本中,legacy version用于进行版本协商,并代表客户端支持的最高版本。在TLS1.3中客户端在supported_versions扩展名中添加客户端所支持的TLS版本列表,与此同时,legacy_version必须设置为0x0303,即TLS1.2的版本号。
如图1所示,这是一个TLS 1.3 的client hello,其version是0x0303,它有一个supported_versions的扩展字段,里面支持的最高协议是TLS1.3(0x0304).

legacy_session_id
TLS1.3中不再使用SessionID进行会话恢复,这一特性已经和预共享密钥PSK合并了,设置这个字段的意义,主要也是为了兼容之前版本,如果 Client 有 TLS 1.3 版本之前的 Server 设置的缓存 Session ID,那么这个字段要填上这个 ID 值。兼容模式下,这个值必须是非空的,所以如果Client不能提供之前版本的值,那么需要重新生成一个32字节的值。

密钥交换
客户端在“Client Hello”消息里直接用“supported_groups”带上支持的曲线,比如 P-256、x25519,

 enum {

          /* Elliptic Curve Groups (ECDHE) */
          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
          x25519(0x001D), x448(0x001E),

          /* Finite Field Groups (DHE) */
          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
          ffdhe6144(0x0103), ffdhe8192(0x0104),

          /* Reserved Code Points */
          ffdhe_private_use(0x01FC..0x01FF),
          ecdhe_private_use(0xFE00..0xFEFF),
          (0xFFFF)
      } NamedGroup;
 struct {
          NamedGroup named_group_list<2..2^16-1>;
      } NamedGroupList;

用“key_share”带上曲线对应的客户端公钥参数,

   struct {
          NamedGroup group;
          opaque key_exchange<1..2^16-1>;
      } KeyShareEntry;

用“signature_algorithms”带上签名算法。

除此以外,TLS1.3 还引入了“0-RTT”握手,用“pre_shared_key”和“early_data”扩展,在 TCP 连接后立即就建立安全连接发送加密消息,不过这需要有一些前提条件。在图1的抓包中没有这两项,这里提一下。

server hello

server hello 的格式如下所示:

struct {
       ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
       Random random;
       opaque legacy_session_id_echo<0..32>;
       CipherSuite cipher_suite;
       uint8 legacy_compression_method = 0;
       Extension extensions<6..2^16-1>;
 } ServerHello;

通过访问测试网站使用wireshark抓包,得到了server hello的包
在这里插入图片描述

小结
TLS 1.3 中优化握手:

client发送clientHello(extension)消息,extension中的support_groups中携带client支持的椭圆曲线的类型,并且在扩展key_share中计算出了相对应的公钥,一起发送给server.

server收到clientHello后会首先选择相应的椭圆曲线参数计算自身的公钥,从key_share扩展中提取相应的公钥作为密钥协商的参数,计算主密钥,并且把自身计算出的公钥放到serverHello的扩展key_share中,然后发送serverHello等消息给client,Client从key_share中取出公钥计算主密钥。

TLS1.2和TLS1.3 对比

1、密钥协商机制改变

TLS1.3借助扩展进行密钥交换,TLS1.3只需要三次握手交互,TLS1.2则需要四次握手。

首先看TLS1.2,它通过KeyExchange进行密钥协商,即ServerKeyExchange和ClientKeyExchange,那么密钥交换本身就需要一个交互来回,所以总共有四次握手交互。
在这里插入图片描述
再看TLS1.3,通过ClientHello和ServerHello的扩展进行密钥交换,那么就省去了1.2版本中KeyExchange的过程,也就省去了一次握手。
在这里插入图片描述

2、添加0-RTT模式,以某些安全属性为代价。

当client和server共享一个预共享密钥PSK(从外部获得或通过一个以前的握手获得)时,TLS 1.3允许client在第一个发送出去的消息的early data中携带数据,client使用这个PSK来认证server并加密early data。即在握手之前就有了PSK时,在第一次发送ClientHello时就可以发送加密数据,达到0-RTT数据传输的目的。
在这里插入图片描述

但是,0-RTT数据的安全性会降低(缺少前向安全)。

3、ServerHello之后的所有握手消息都被加密,引入了加密扩展EncryptedExtension。

4、全面使用ECC密码算法,删除不具有前向安全的密码套件。

5、其他还包括新的密钥派生函数,删除多余的报文消息(ChangeCipherSpec,但我抓包测试时还是有),以及其他算法的改进。

参考文章
https://blog.csdn.net/qq_35324057/article/details/105366368
https://zhuanlan.zhihu.com/p/55911409
https://zhuanlan.zhihu.com/p/28850798
https://halfrost.com/tls1-3_start/
https://blog.csdn.net/qq_36058927/article/details/105918388
https://www.liaoxuefeng.com/wiki/1252599548343744/1304227905273889(DH算法入门案例)


  1. 测试地址:https://halfrost.com/tls1-3_start/ ↩︎

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值