在开始之前先问几个问题:
- TLS和SSL有什么异同?
- TLS1.3做了什么改进?
- HTTPS握手的整套流程是什么?
本文不打算介绍对称密钥、非对称密钥和哈希算法的知识,但是会简单介绍下数字证书。数字证书简单来说就是有上面有对应的公钥以及其他的信息,然后CA会用CA自己的私钥对这些信息进行签名,也就是CA认证了这些信息,那么就无法伪造了。
具体流程
通过在ubuntu
上通过tcpdump port 443 -w https.pcap
抓取数据包,然后放到wireshark
里面进行分析,其中这些流量是通过访问https://baidu.com
来获取到的。
下面的每一个部分都是对应其中的一个数据包。
首先是前三个包,很简单,就是TCP的三次握手过程,这里就不展开了。
Client Hello
然后第四个包开始,可以发现是客户端主动发送了一个client hello的包给服务器,而且这个包的协议是TLSv1.2的。
稍微对这个包进行分析下:
比较重要的就是会携带一个随机数,然后会发送客户端支持哪些加密套件和支持的压缩算法给服务器。
然后,服务器回送了一个ACK的包(最上面图中的第五个包)。
Server Hello
紧接着发完ACK之后,服务器立马回送了一个Server Hello的包。来看看这个包具体解析:
从图中看到,也是携带了一个随机数,并且确定了到底用的是什么加密套件,并且压缩算法不使用。
注意!这里使用了DH作为密钥交换的算法,实际中也可能会使用RSA作为密钥交换。
Certificate & Server Key Exchange & Server Hello Done
紧接着,Server马上又发送了一个包,然后这个包就有点特殊了,它其实是由两个包组合在一起的,这里打算分开讲述这两个包。
Certificate
其实就是服务器的证书,具体如下所示:
其中一个很明显是百度的,长度是1834;第二个根据名字也可以看出是一个CA的证书,具体内容就不展开了。
Server Key Exchange & Server Hello Done
接下来是密钥的交换,这里直接用的是DH密钥交换:
这里就完成了server的证书发送和DH密钥交换参数的交换。
仔细看,在DH密钥交换参数的下面,还有一个signature,这个签名,是服务器用自己的私钥,把前面两个随机数+DH参数进行数字签名之后的签名,也附带发送给了浏览器。
接下来就是对上面的server hello 和 certificate & server key exchange的两个ACK包。
Client Key Exchange & Change cipher Spec & Encrypted Handshake Message
这三步都在上面的图中了。
第一步是需要在本地生成DH参数,发送出去。服务器只要收到了之后,就可以得到预主密钥了。
然后可以根据预主秘钥 + 两个随机数得到最终使用的对称密钥了,具体算法如下:
master_secret = PRF(pre_master_secret,"master secret",ClientHello.random+ServerHello.random)
第二步是Change cipher Spec,简单来说就是浏览器和服务器目前应该已经协商得到了密钥,那么就应该更改密码规范了。
最后一步是Encrypted Handshake Message,浏览器会用协商出的密钥加密之前握手的信息,看服务器能不能解密。
Change Cipher Spec & Encrypted Handshake Message
服务器也需要确认,已经把密码规范改掉了,然后加密了对应的握手信息。
愉快通信
到了这里,说明所有的消息都没有问题,浏览器也确认了服务器确实是自己需要访问的那个,且浏览器也已经和服务器协商出了真正的密钥,那么接下来双方就可以根据这个密钥来加密应用层的消息了。
其他
其实眼尖的话还能发现第一张图里面还有一个Encrypted Alert
,这个的意思是加密通信需要结束了,警告对面不要再发送包含有敏感信息的内容了(浏览器和服务器都可以发这个)。而这里明显就是已经把内容发完了,所以才会发这个包。
RSA相比DH来说更简单,因为RSA只需要利用证书的公钥来加密一个随机数,就可以让客户端和服务器同时得到相同的密钥了。
当然最后就是TCP的四次挥手了。
总结
如何和面试官谈HTTPS(DH版本):
- 浏览器发送一个Client Hello,告知自己支持的协议、加密套件、压缩算法以及随机数A。
- 服务器回送一个Server Hello,选择对应的加密套件、压缩算法,并且回送随机数B。
- 紧接着,服务器发送证书、DH算法的参数给浏览器。
- 浏览器也会生成DH算法的参数,发送给服务器,并且发送密码规范改变、以及用密钥加密的握手的内容。
- 服务器也发送密码规范改变,以及用密钥加密的握手内容。
加分点:
- 如果能提到
Encrypted Alert
,感觉会有比较深入的理解。 - 如果能同时提到RSA和DH这两种,也是一个不错的加分项。
TLS和SSL的异同
简单来说,SSL是网景公司(NetScape)的产物,而TLS则是互联网标准化组织的产物。
1994年SSL1.0问世,但是没有被发布。1995年SSL2.0发布,但是有严重的漏洞。1996年SSL3.0发布,得到了大规模的应用。
互联网标准化组织在1999年的时候,发布了SSL的升级版本——TLS1.0
2006年升级成了TLS1.1,2008年的时候升级成了TLS1.2版本。
也就是可以说TLS就是SSL的升级版。
TLS1.3 升级
2018年,TLS1.3正式发布了,那么它带来了什么升级变动呢?
- 将大幅改进握手,注重隐私,在握手尽可能早的阶段加密信息,Server Hello之后的所有消息都是加密的,客户端只需要一次往返就能与服务器建立安全和验证的连接。
- 其他看了也记不住,算了。