3.3 HTTPS RSA握手解析
TLS握手过程
http是明文传输,客户端与服务端通信的信息都是肉眼可见的,随意使用一个抓包工具都可以截获通信的内容。
存在安全风险:
- 窃听风险,比如通信链路上可以获取通信内容。
- 纂改风险,比如强制植入广告。
- 冒充风险,比如冒充淘宝网站。
HTTPS在http与TCP层之间加入了TLS协议,解决上述风险。
TLS如何解决http的风险?
- 信息加密:http交互信息是被加密的,第三方就无法窃取;
- 校验机制:校验信息传输过程中是否有被第三方纂改过,如果纂改过,则会有警告提示。
- 身份证书:证明淘宝是真的淘宝网。
在进行HTTP通信前,需要先进行TLS握手。
通常经过“四个消息”就可以完成TLS握手,也就是需要2个RTT时延。HTTPS是应用层协议,需要先完成TCP连接建立,然后走TLS握手过程,才能建立通信安全的连接。
不同的密钥交换算法,TLS握手过程可能会有一些区别。密钥交换算法:考虑到性能的问题,双方在加密应用信息时使用对称加密密钥,而对称加密密钥是不能被泄漏的,为了保证对称加密密钥的安全性,使用非对称加密的方式来保护对称加密密钥的协商。
RAS握手过程
传统的TLS握手基本都是使用RAS算法来实现密钥交换的。在TLS证书部署服务端时,证书文件其实就是服务端的公钥,会在TLS握手阶段传递给客户端,而服务端的私钥一直留在服务端,一定要确保私钥不能被窃取。
在RAS密钥协商算法中,客户端会生成随机密钥,并使用服务器的公钥加密后再传给服务器。根据非对称加密算法,公钥加密的消息仅能通过私钥解密。这样服务器解密后,双方就得到了相同的密钥,再用它加密应用消息。
TLS第一次握手
客户端首先会发一个[Client Hello]消息,跟服务器[打招呼].
消息里有客户端使用的TLS版本、支持的密码套件列表,以及生成的随机数(Client Random),这个随机数会被服务器保留,它是生成对称加密密钥的材料之一。
TLS第二次握手
当服务器收到客户端的[Client Hello]消息,会确定TLS版本是否支持,从密码套件列表中选择一个密码套件,以及生成随机数(Server Random)
接着,返回[Server Hello]消息,消息里面有服务器确认的TLS版本号,给出随机数(Server Random),然后从客户端套件列表选择一个合适的密码套件。
服务器选择的密码套件: “Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256”。
- 由于WITH单词前只有一个RSA,则说明握手时密钥交换算法和签名算法都是使用RSA;
- 握手后通信使用ASE对称算法,密钥长度128位,分组模式是GCM
- 摘要算法SHA256用于消息认证和产生随机数。
随机数是后续作为生成[会话密钥]的条件,会话密钥就是数据传输时,所使用的对称加密密钥。
密码套件的基本形式是:[密钥交换算法+签名算法+对称加密算法+摘要算法],一般WITH单词前面有两个单词,第一个单词是约定密钥交换的算法,第二个单词是约定证书的验证算法。
然后,服务器为了证明自己的身份,会发送[Server Certificate]给客户端,这个消息里含有数字证书。
随后,服务端发送[Server Hello Done]消息,目的是告诉客户端,已把该给的东西都给你了,本次打招呼完毕。
TLS第三次握手
客户端验证完证书后,则认为可信则继续往下走。
接着,客户端就会生成一个新的随机数(pre-master),用服务器的RSA公钥加密该随机数,通过[Client Key Exchange]消息传给服务端。
服务器收到后,用RSA私钥解密,得到客户端发来的随机数(pre-master).
至此,客户端和服务端双方都共享了三个随机数,分别是Client Random、Server Random、pre-master.
于是,双方根据已经得到的三个随机数,生成会话密钥(Master Secret),它是对称密钥,用于后续HTTP请求/响应的数据加解密。
生成==[会话密钥]==后,客户端发送[Change Ciper Spec](更改密码规则),告诉服务器开始使用加密方式发送消息。
然后,客户端再发一个[Encrypted Handshake Message(Finished)]消息,把之前所有发送的数据做个摘要,再用会话密钥加密一下,让服务器做个验证,验证加密通信是否可用和之前握手信息是否有被中途篡改过。
可以发现,[Change Ciper Spec]之前传输的TLS握手数据都是明文,之后都是对称密钥加密的密文。
TLS第四次握手
服务器也是同样的操作,发送[Change Ciper Spec]和[Encrypted Handshake Message(Finished)]消息,如果双方验证加密和解密都没有问题,那么握手正式完成。
最后,就是[会话密钥]加解密HTTP请求和响应了。
客户端验证证书
数字证书和CA机构
一个数字证书通常包括:
- 公钥
- 持有者信息
- 证书认证机构(CA)的信息
- CA对这份文件的数字签名及使用的算法
- 证书有效期
- 还有一些额外信息
数字证书是用来认证公钥持有者的身份,以防止第三方进行冒充。证书就是用来告诉客户端,该服务器是否是合法的,因为只有证书合法,才代表服务端身份是可信的。
为了让服务器的公钥被大家信任,服务器的证书都是由==CA(Certificate Authority,证书认证机构)==签名的,CA就是网络世界的公安局、公证中心,具有极高的可信度,所以由它来给各个公钥签名,信任的一方签发的证书,那证书也是被信任的。
签名的作用是避免中间人在获取证书时对证书内容进行篡改。
数字证书签发和验证流程
CA签发证书的过程,如上图左边部分:
- 首先CA会把持有者的公钥、用途、颁发者、有效时间等消息打成一个包,然后对这些信息进行Hash计算,得到一个Hash值
- 然后CA会使用自己的私钥将该Hash值加密,生成Certificate Signature,也就是CA对证书做了签名
- 最后将Certificate Signature添加在文件证书上,形成数字证书
客户端校验服务器的数字证书的过程,如上图的右边部分:
- 首先客户端会使用同样的Hash算法获取证书的Hash值H1;
- 通常浏览器和操作系统中集成了CA的公钥信息,浏览器收到证书后可以使用CA的公钥解密Certificate Signature内容,得到一个Hash值H2;
- 最后比较H1和H2,如果值相同,则为可信赖的证书,否则认为证书不可信。
证书链
最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书,于是客户端也信任 baidu.com 证书。
操作系统一般都会内置一些根证书,比如:
这样一层层地验证就构成了一条信任地链路,整个证书信任链验证流程如下图所示:
为确保根证书地绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。
RAS算法的缺陷
使用RSA密钥协商算法的最大问题是不支持前向保密。
因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务器收到后,会用私钥解密得到随机数。所以一旦服务器的私钥泄漏了,过去被第三方截获的所有TLS通讯密文都会被破解。