tls1.3协议实战(一)---client hello和server hello解析
1、根据公开资料显示,xxxx的聊天通信协议mmtls是基于tls 1.3精简了一些握手的方法后用openssl实现的;官方的介绍在这:https://mp.weixin.qq.com/s/tvngTp6NoTZ15Yc206v8fQ ;为了便于理解、抓住主脉络,我这里整理了整个协议的主干思路,如下:
完整的TLS流如下:
下面挨个分析这些包的作用和重要字段的意义!
- 老规矩,主动向server打招呼的时候先做个自我介绍:这个是handshake握手包,版本是1.0(我暂时也不知道为什么是这个),这个包的长度是512字节;(注意: tcp协议的缺点之一:必须明文指定包长度!接收方按照指定的长度读取数据。windows下有个 CVE-2020-16898 "Bad Neighbor " https://www.cnblogs.com/theseventhson/p/14004712.html 就是因为内核驱动没处理好接受的数据包长度导致蓝屏;这个地方还有可能利用整数溢出漏洞,进而导致缓冲区溢出)
接下来是核心的handshake protocol解析,如下:字段有很多,我们挨个看
前面3个handshake type、length、version都是常规的介绍,看英文不解释都能懂!从第4个开始:
- random:client随机生成一个32byte的数发给server。通常,在通信中以访给另一方发随机数的作用有:1)防止重放攻击 2)后续用于完整性校验,这里也不例外 3)生成encrypt-key,正式开始加密应用层的数据;
- session ID:双方通信的一般套路都是“非对称算法协商密钥,对称算法加密数据”。服务器生成session id,存放本次session协商好的对称密钥。下次通信时,客户端带上session id,server就知道用哪个对称密钥继续加密数据了。不过session id有些缺陷(id一般都存在单个服务器,但客户端的数据一般都是反向代理、负载均衡等转发到内部某个server的,这些反向代理、负载均衡是不知道session id属于哪个server),已经被session ticket替代;
- cipher suites:client列举自己支持的加密套件,可以看出前面一般是非对称加密算法,协商对称算法密钥的。后面都是加密应用数据的对称算法;后续server会根据自己的实际情况选择合适的加密套件;这里稍微解释一下这些加密套件的基础算法,比如:0xc02b,ECDHE,是双方用来协商对称密钥的椭圆曲线算法;ECDSA是客户端验证服务端的签名算法;AES_128_GCM_SHA256是128bit的对称加密算法,同时带了数据校验功能,可有效识别传输的数据是否被篡改!
- extension:有好多分项,都有不同的含义,先看第一个:说明server name。这里访问的是gstatic,貌似是google的广告联盟站点。我并没有访问这个,估计是访问google时自带的;
- supported groups:由于安全性和效率问题,tls1.3已经不再使用RSA,而是椭圆曲线。不同的椭圆曲线对应不同的曲线形状,会产生不同的公钥;同样,不同的基点G也会导致产生不同的公钥,所以这里有4种不同的椭圆曲线参数供client选择;
- session ticket:作用和session id类似,上面已经解释过了。这里由于还是client hello阶段,所以这个字段暂时没有值;保留字段,带上空值,也可以向服务器标明client支持session ticket功能;
- application layer protocol negotiation:协商tls上层的应用层协议,这里采用的是http协议
- key share:这个是重点!tls1.3支持1-RTT,比tls1.2效率提升一倍,原因就在这里了:在client hello里面,client列举出了自己支持的加密套件,并把所有的非对称加密算法的公钥都一并带上(虽说这里只有1种,我怀疑是浏览器的问题)。server收到后可以直接根据接受的ECDHE和client的公钥生成自己的公钥和对称密钥;
- PSK exchange models:psk_dhe_ke=1,这里双方约定用非对称加密方法ECDHE协商一个对称密钥,或则直接从之前协商出来的密钥参数中得出一个密钥(psk_ke);
- supported version:支持的tls版本,这里大概是为了兼容老版本,从tls1.0到1.3都支持
- pre-shared key:访问googke另一个分站点的时候,抓到了PSK的字段,如下:(1)psk本质也是一串ID,这里有226byte,生成方式见本文上方的那张图,最早是server和client通过tls成功握手后把key和其他一些信息通过HMAC转换后发给client;client后续访问可以直接带上这个PSK,就不用再做密钥协商,节约时间;(2)这里还有个obfuscated ticket age: 1874391131,转成年月日的格式就是2029-05-25 16:12:11,这是PSK的生存时间,过期就用不了了。
注意几个容易混淆的概念:
- key_share:椭圆曲线中双方互换公钥来生成对称加密的私钥; pre_shared_key:是预共享秘钥认证机制PSK生成的对称秘钥,PSK也是一种身份认证机制;
- psk其实即使Session ticket外加一些检验的东西,相当于ticket的强化版!
上面介绍了那么多extension,有4个extension是必须的:psk_key_exchange_modes、pre_shared_key、key_share、supported_versions;
(2)server hello:先来看前面遗留的第一个问题:为啥client hello之后server先发一个ack给client,再发server hello了?而不是直接发个server hello?
server hello要根据client的加密套件、公钥继续算出自己公钥和私钥(32byte=258bit),这种big num的计算是相当耗时的(这里花了约440ms)。如果server在收到client hello后不马上回复ACK,而是等计算出自己公钥和私钥再回复client,搞不好client会认为server已经超时挂掉,所以server先发个ACK,让client知道他的hello包已经被收到!
和分析client hello包一样,接下来挨个分析重要字段的含义:
- 还是标明这个包的作用是handshake,长度122字节,版本是1.2(也不知道为啥不标注1.3)......
- Random: 32byte的随机数,作用和之前client发给server的随机数一样,1)防止重放 2)后续用于消息完整性校验,防止被篡改 3)生成encrypt-key,正式开始加密应用层的数据;
- session id:32byte,作用在client那里已经解释了
- Cipher Suite:client在client hello包里面列举了其能支持的加密套件,这里server在里面选择了这个加密套件;后续双方就用AES_GCM来做对称加密;
- Extensions:最重要的莫过于key_share了。对称加密算法是AES_GCM,那么密钥又是啥了? 就是通过椭圆曲线计算出来的;Client在hello包里已经给server发送了他的公钥,server也要把自己的公钥发给client,双方才能计算出对称加密的密钥,所以server这里选择了x25519(这个其实是client选择的,server只能遵从)。
- Change Cipher Spec:告诉client,后续咋们通信时改变现在的加密方式,即改成对称密钥加密通信数据;
剩下的问题又来了:wireshark就解析到了0xba这个位置,从0xbb到0x58e=1422的位置,还有1234byte并未解析,这些又都是什么数据了?纵观整个协议的握手过程,截至目前看到的都是handshake密钥交换阶段,record传输加密数据的阶段都在哪了?
4、总结:
(1) 刚开始学的时候,对session id、ticket、psk理解不够透彻,很多概念的解释看的云里雾里,这里系统性对比和总结这3个概念的区别,希望对读者有所帮助;这些概念或事物的宗旨很简单:对称加密的密钥是经过多个RTT协商而来的,耗时非常长,对服务器CPU算力的消耗也不小,来之不易,需要好好保存,下次通信时如果能继续复用就太好了,下面3个本质上都是保存对称加密密钥的方法!
(2)整个过程涉及到client和server双方互换公钥和生成对称密钥。期间只有client验证server,并没有server验证client,这里有个缺陷:如果黑客冒充client(这个不难,比如随机更换源IP,导致server认为是来自不同client的包),随机生成各种公钥(甚至都不用随机生成,而是直接写死),server接收到client的公钥后要需要耗费算计去计算对称密钥。如果黑客伪造的client达到一定数量,理论上可以导致server的CPU耗尽,无法再接受正常client的链接请求,这也是常见的DOS攻击之一!
参考:
1、https://blog.csdn.net/SkyChaserYu/article/details/105840504 tls1.3抓包分析
2、https://time.geekbang.org/comment/nice/111287 session id、session ticket、psk三者区别和联系
3、https://halfrost.com/https_tls1-3_handshake/ 直观感受tls握手流程
4、https://jasonlees.netlify.app/article/tcpip-4-ssl-tls-3/ TCP/IP系列(4)-SSL/TSL详解(3)
5、https://cshihong.github.io/2019/05/09/SSL%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/ SSL协议详解