前言
如果还没尝试过使用wiresharp
的话,可以参照我之前写过的文章《wireSharp的基本用法》 (opens new window)。
本篇文章不会详细说TLS
的内容,请结合我上一篇文章《深入TLS/SSL协议》 (opens new window)一起观看。
Handshake
基本概念
TLS1.2
中的握手过程主要有三个目的:
- 验证身份
- 达成安全套件共识
- 传递密钥
如图所示:
1、客户端发送一个Client Hello
,包含:
- 协议版本号。
- 客户端生成的随机数-
Client random
。 - 客户端所支持的安全套件列表。
2、服务器回一个Server Hello
,包括:
server
所选择的安全套件。server
发送自己的数字证书-server Certificates
。server
发送自己生成的公钥-serverKey
。
3、客户端发送自己生成的公钥-clientKey
。
4、客户端与服务器根据自己的私钥与对方的公钥生成对称加密的密钥。
5、进行加密通讯
使用wiresharp抓包分析
下面抓取www.juejin.im
为例:
1、Client hello
:
- 协议版本号
Version:TLS 1.2
- 随机数
Random
- 支持17种安全套件的列表
2、Server hello
中:
协议版本号
Version:TLS 1.2
选中了一个安全套件:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
随机数
Random
发送数字证书:
发送
server
的公钥以及所用的签名算法:
3、Client
发送自己的公钥
4、client
与server
根据自己的私钥与对方的公钥生成对称加密的密钥
5、Change Cipher Spec
这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的密钥加密了并通知server
握手结束。
6、Change Cipher Spec
这一步是服务端通知客户端后面再发送的消息都会使用加密并通知client
握手结束。
TLS1.3握手
TLS1.3
中,大大减少了所支持的安全套件。比如在openssl1.1
中只支持5种安全套件
TLS13-AES-256-GCM-SHA384
TLS13-CHACHA20-POLY1305-SHA256
TLS-AES-128-GCM-SHA256
TLS-AES-128-CCM-8-SHA256
TLS-AES-128-CCM-SHA256
TLS1.3
握手的变化:
由于安全套件的减少,client
可以在第一次请求中将5种安全套件全部生成一对密钥,将5种publicKey
发送给server
,然后server
选择其中一种安全套件来生成自己的一对密钥。从而相比上面说的TLS1.2的握手过程减少了一次RTT
。
握手过程的优化
TLS
握手中消耗的那一个或两个RTT
时间是对于安全性而言的。
但对于应用层的信息传递而言并没有意义。
所以TLS
提供了许多种手段来减少握手过程中所消耗的RTT
的时间。比如:session
缓存、ticket
票据等
session缓存
第一次握手后服务器会生成一个sessionID
,然后传给浏览器。
在一定时间内,比如几个小时、几天内。浏览器携带这个sessionID
再次访问服务器时,服务器会从缓存中提取这个sessionID
所指向的加密密钥。没有必要再次根据ECDH
协议生成新的密钥,从而减少消耗的RTT
时间。
下面以百度站点为例:
当再次访问百度站点时,client hello
就会携带一个sessionID
:
而client Hello
步骤之后直接到了Change Cipher Spec
。并没有进行DH
或者ECDH
密钥交换协议
Change Cipher Spec
里面就告诉Client
,使用之前的密钥
ticket票据
与sesion
机制不同的是,ticket
机制不需要server
花费缓存来存放。而是基于一个独特的密码,这个密码是集群中所共享的。基于这个密码将ticket
解密后,就可以获取到上一次生成的密钥。
TLS1.3中的0RTT握手
所谓0RTT
,指的是:第一次请求时就携带GET
数据,在一次RTT
后就马上得到RESPONSE
。握手时间就是0RTT
了。
事实上这也是第二次握手中才有的。当第一次握手时,client
与server
就会把密钥信息缓存下来。第二次访问时,基于第一次缓存的,基于一定时间内有效的信息对报文进行加密。
重放攻击
无论是session
、ticket
还是TLS1.3
中的0RTT
都面临着一个危险:重放攻击
如图所示:
如果Client
发送一个使用上一次的密钥加密的post
请求给server
,而通常一个post
请求是会改变数据库的。
如果这个报文被中间人获取下来了,而且并不需要解密这份报文。然后在随后的时间内,不断的发送这个报文,就可以不断的改变数据库以造成攻击效果。
所以设定一个合适的过期时间是必要的。