应用安装
wireshark设置
选择网卡
因为我用的是windows11,本机上请求比较繁杂,所以我选择的是wsl子系统,后续的请求我也是在wsl中发起的,可以根据自己的实际情况具体选择,选好后直接双击就可以进入抓取界面。
设置视图
此设置是为了显示请求的域名,后续将域名作为过滤条件的时候就能生效。
设置过滤条件
将过滤条件ip.src_host contains "csdn" or ip.dst_host contains "csdn"
粘贴到筛选框中,然后开始抓取。
RSA握手分析
打开终端(如果跟我一样是子系统那就打开wsl终端),输入命令:
curl --ciphers AES256-SHA256 https://blog.csdn.net
命令中加入参数--ciphers AES256-SHA256
是为了指定加密套件使用RSA,然后在wireshark中查看抓取结果,可以看到已经抓到了TLS握手过程的请求了。
第一次握手 Client Hello
- Random:客户端生成的随机数
- Cipher Suites:客户端支持的加密套件
客户端生成随着数Random,然后将TLS版本、客户端随机数Random、客户端支持的加密套件Cipher Suites发送到服务端。
第二次握手 Server Hello
- Random:服务端生成的随机数
- Cipher Suite:服务端选用的加密套件(与客户端协商共同使用的加密套件)
服务端接收到客户端的Client Hello后,服务端这边生成随机数Random,然后将服务端随机数、服务端选择的TLS版本、服务端选择的加密套件Cipher Suite发送给客户端。
支持客户端与服务端已经协商好了TLS版本和使用的加密套件,并且都拥有了双方生成的随机数。
因为请求的时候指定了参数--ciphers AES256-SHA256
,可以看到服务端这边选择的加密套件就是TLS_RSA_WITH_AES_256_CBC_SHA256
,意思就是本次TLS握手使用RSA密钥协商算法(目前基本已经不用这个了,原因后面说)。
客户端验证证书
接下来,在继续之后的握手步骤之前,客户端需要先验证一下证书,拿到证书中的公钥,也即服务端使用的公钥。
Certificate
服务端将证书发给客户端,客户端对证书进行验证,验证成功后客户端后续就可以使用服务端(证书中)提供的RSA公钥了。
证书验证在此处不是介绍重点,感兴趣的可以单独去查查。
Server Hello Done
这个表示服务器已经接受了客户端的hello消息,并且已经从中选择了一个密码套件(Cipher Suite),同时也向客户端发送了自己的hello消息,以及服务器使用的密码套件和其他的相关信息。这意味着服务器和客户端已经就双方协商使用的加密算法、密钥长度、认证方式等相关信息达成了一致,并且接下来的通信将在双方协商确定的密码套件的保护下进行。如果客户端也接受了该密码套件并向服务器发送了确认信息,那么 TLS 握手将在 ServerHello Done 步骤之后继续进行。并最终建立起一条安全的TLS/SSL连接。
第三次握手
上一步客户端完成证书验证后,继续往下走。
我们知道,TLS 的密钥协商是一个非对称加密的过程,也就是说客户端和服务器使用不同的密钥。在这个过程中,客户端生成一个“PreMaster Secret(预主密钥)”,将该密钥通过服务器的RSA公钥进行加密,然后发送给服务器。服务器收到“PreMaster Secret”后通过RSA私钥进行解密,得到“PreMaster Secret”加密前的值。
至此,客户端服务端都拥有了三个随机数,分别是Client Random、Server Random和PreMaster Secret,双方就可以根据这三个随机数,生成一个会话密钥Master Secret用于后续请求以及响应数据的加密。
接着通过发送 Change Cipher Spec 消息,表示客户端和服务器都要改变加密规范,也就是改变所使用的加密算法和密钥(密钥就是Master Secret)。同时,在发送之前,两端使用未加密的通信方式进行确认,以保证此时双方使用的加密算法和密钥是一致的。
最后客户端发送一个Encrypted Handshake Message
消息,将之前客户端和服务器在握手协议过程中完成了的对称加密算法和密钥的协商结果,加密后发送给了服务端,服务端可以通过之前协商的加密算法和密钥对此消息进行验证(可以看出,之前的消息都是明文,直至这个消息开始都变成密文)。
第四次握手
服务器这边也是一样的操作,先声明改版加密规范,然后发送一个对之前握手协商结果的加密的消息给客户端。
至此RSA的TLS握手过程结束,后续都是加密的应用数据。
RSA过程图解
文字容易忘记,还是画个图能更清晰。
RSA协商算法存在一个致命的问题,就是不支持前向保密。
因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。
为了解决这个问题,后面就出现了 ECDHE 密钥协商算法,我们现在大多数网站使用的正是 ECDHE 密钥协商算法。