TLS握手流程
复习一遍HTTPS协议
Overview👓
由于HTTP是明文传输,因此存在被窃听、纂改、冒充的风险,HTTPS在HTTP和TCP层之间加入了TLS协议
TLS提供了信息加密、信息校验和身份验证,来解决HTTP存在的问题。
TLS的四次握手如下:

TCP连接建立完成后,然后走完TLS握手后,才能建立起安全的通信连接,接下来应用数据的传输都是通过非对称加密,而这个对称密钥由TLS四次握手中生成。
HandShake👋
将TLS证书部署服务端时,证书文件中包含一对公私钥,公钥会在TLS握手阶段传递给客户端,私钥由服务端保管。
浏览器拿到服务端的证书,会判断证书是否被CA(Certificate Authority,证书认证中心)认证,且在有效期内。
第一次握手
客户端发送一个Client Hello
的消息

包括客户端使用的TLS版本号、支持的密码套件列表、生成的随机数(Client Random),这个随机数会被服务端保留,作为生成对称密钥的参数之一
第二次握手
服务端收到客户端的Client Hello
消息后,会确认TLS版本是否支持,从密码套件列表中选择一个密码套件,以及生成随机数(Server Random)
密码套件的名称有固定格式,密钥交换算法+签名算法 WITH 对称加密算法+摘要算法
比如下面的密码套件:
密钥协商算法:ECDHE
签名算法:RSA
握手后的通信:AES,密钥长度128位,分组模式GCM
摘要算法:SHA256,用于消息认证和产生随机数

接着服务端为了证明自己的身份,发送Certificate
消息,将证书发送给客户端

发送完证书后,发送Server Key Exchange
和Server Hello Done
消息

服务端选择了名为named_curve
的椭圆曲线,生成随机数作为椭圆曲线的私钥,并根据基点G和私钥计算出椭圆曲线公钥,将公钥发送给客户端,并对公钥进行RSA签名,防止第三方篡改。
若为RSA密钥协商算法,这里只会发送Server Hello Done
消息
第三次握手
客户端收到服务端的证书,校验证书是否合法。通过证书链逐级验证以确认证书的真实性,再用证书的公钥验证签名。以此确认服务端身份。
客户端生成一个随机数作为客户端椭圆曲线的私钥,再根据服务端之前给的信息,生成客户端的椭圆曲线公钥。发送Client Key Exchange
消息给服务端

至此,双方都有对方的椭圆曲线公钥、自己的椭圆曲线私钥,双方计算出点(x, y)
最终 客户端随机数 + 服务端随机数 + x
得到共享密钥
之后客户端发送Change Cipher Spec
消息,通知服务端后续改用对称算法加密通信
再发送Encrypted Handshake Message
,把之前发送的数据做一个摘要,再用对称密钥加密,让服务端做验证。

若为RSA密钥协商算法,这里客户端会生成一个随机数pre-master
,并用服务端的RSA公钥加密该随机数,发送Client Key Exchange
消息将加密的pre-master
发送过去。服务端收到后,⽤RSA私钥解密,得到客户端发来的随机数pre-master
,然后用 客户端随机数 + 服务端随机数 + pre-master
得到共享密钥,后续一样。
第四次握手
服务端也会发Change Cipher Spec
和Encrypted Handshake Message
消息,如果双⽅都验证加密和解密没问题,那么握⼿正式完成。接下来可以正常收发加密的 HTTP 请求和响应了
RSA Diff ECDHE
使用RSA密钥协商算法的一个问题就是不支持前向保密(forward security),一旦服务端的私钥泄露(攻击者用来解密pre-master
),过去被第三方截获的所有TLS通讯密文都会被破解
前向保密:用来产生会话密钥(session key)的长期密钥(long-term key)泄露出去,不会造成之前通讯时使用的会话密钥(session key)的泄露,也就不会暴露以前的通讯内容
下面复习一下Diffie-Hellman密钥协商算法

客户端和服务端互相传递自己的公钥,双方根据各自持有的密钥能够算出一个相同的值,这个值用于后面对称加密使用。
由于每⼀次对称加密密钥都是实时⽣成的,因此能够保证前向保密。
DH是非对称加密算法,主要用于密钥交换,基于离散对数问题。

底数a和模数p是离散对数的公共参数,b是真数,i是对数。由对数算出真数很容易,但由真数反推对数却很困难。
当p为很大的指数时,求解对数i就是一个数学难题。
准备:Alice和Bob协商好一个大素数q和q的一个本原元 α, 1< α <q , q 和 α公开

为了安全通信,每次双方都重新生成随机数,因此也叫DHE算法(E:ephermeral临时性的)
为了提升DH算法的性能,出现了现在⼴泛⽤于密钥交换算法 —— ECDHE 算法。 ECDHE 算法是在 DHE 算法的基础上利⽤了 ECC 椭圆曲线特性,可以⽤更少的计算量计算出公钥,以及最终的会 话密钥。
CA
一个数字证书通常包含如下内容:
公钥
证书持有者信息
证书认证机构CA的信息
CA对证书的数字签名及使用的算法
证书的有效期
一些额外信息
证书用来认证公钥持有者的身份,以防第三方冒充

实际上,证书的验证过程中还存在⼀个证书信任链的问题,因为我们向 CA 申请的证书⼀般不是根证书签发的, ⽽是由中间证书签发的。比如查看百度的证书

客户端会逐级向上验证证书,直到根证书。操作系统⾥⼀般都会内置⼀些根证书

之所以存在中间证书,是为了确保根证书的绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。
Cer Transfer
相同安全强度下,ECC密钥⻓度⽐RSA短的多,因此服务端的证书应该选择椭圆曲线证书,以减少证书大小,更便于传输。
Cer Verfify
客户端在验证证书时,会⾛证书链逐级验证,验证的过程不仅需要⽤CA公钥验证证书签名,⽽且为了知道证书是否被CA吊销,客户端还会再去访问CA中心,下载CRL或者OCSP数据,以此确认证书的有效性。
CRL
CRL(Certificate Revocation List)证书吊销列表,这个列表是由 CA 定期更新,列表内容都是被撤销信任的证书序号,如果服务器的证书在此列表,就认为证书已经失效,不在的话,则认为证书是有效的。

CRL问题也很明显
实时性差。若一个证书刚被吊销,CRL还没来得及更新,客户端就已经信任了这个证书
CRL传输时延。随着吊销证书增多,CRL这个列表会越来越大,下载速度就会慢,客户端还得遍历一个大列表
OSCP
OSCP(Online Certificate Status Protocol)在线证书状态协议,用于查询证书的有效性,客户端向CA发送查询请求,CA返回证书的有效状态

通常是服务端向CA周期性地查询证书状态,获得⼀个带有时间戳和签名的响应结果并缓存它。当有客户端发起连接请求时,服务端把CA的响应结果在TLS握手
过程发送给客户端。由于有签名的存在,服务端无法篡改,客户端就能得知证书是否被吊销,这样客户端就不用去查询了。

Last updated
Was this helpful?