TLS握手流程

复习一遍HTTPS协议

Overview👓

由于HTTP是明文传输,因此存在被窃听、纂改、冒充的风险,HTTPS在HTTP和TCP层之间加入了TLS协议

TLS提供了信息加密、信息校验和身份验证,来解决HTTP存在的问题。

TLS的四次握手如下:

image-20231007142504804

TCP连接建立完成后,然后走完TLS握手后,才能建立起安全的通信连接,接下来应用数据的传输都是通过非对称加密,而这个对称密钥由TLS四次握手中生成。

HandShake👋

将TLS证书部署服务端时,证书文件中包含一对公私钥,公钥会在TLS握手阶段传递给客户端,私钥由服务端保管。

浏览器拿到服务端的证书,会判断证书是否被CA(Certificate Authority,证书认证中心)认证,且在有效期内。

第一次握手

客户端发送一个Client Hello的消息

image-20231007145351435

包括客户端使用的TLS版本号、支持的密码套件列表、生成的随机数(Client Random),这个随机数会被服务端保留,作为生成对称密钥的参数之一

第二次握手

服务端收到客户端的Client Hello消息后,会确认TLS版本是否支持,从密码套件列表中选择一个密码套件,以及生成随机数(Server Random)

密码套件的名称有固定格式,密钥交换算法+签名算法 WITH 对称加密算法+摘要算法

比如下面的密码套件:

  • 密钥协商算法:ECDHE

  • 签名算法:RSA

  • 握手后的通信:AES,密钥长度128位,分组模式GCM

  • 摘要算法:SHA256,用于消息认证和产生随机数

image-20231007145943590

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

image-20231007152411033

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

image-20231007152723019

服务端选择了名为named_curve的椭圆曲线,生成随机数作为椭圆曲线的私钥,并根据基点G和私钥计算出椭圆曲线公钥,将公钥发送给客户端,并对公钥进行RSA签名,防止第三方篡改。

若为RSA密钥协商算法,这里只会发送Server Hello Done消息

第三次握手

客户端收到服务端的证书,校验证书是否合法。通过证书链逐级验证以确认证书的真实性,再用证书的公钥验证签名。以此确认服务端身份。

客户端生成一个随机数作为客户端椭圆曲线的私钥,再根据服务端之前给的信息,生成客户端的椭圆曲线公钥。发送Client Key Exchange消息给服务端

image-20231007154006809

至此,双方都有对方的椭圆曲线公钥、自己的椭圆曲线私钥,双方计算出点(x, y)

最终 客户端随机数 + 服务端随机数 + x 得到共享密钥

之后客户端发送Change Cipher Spec消息,通知服务端后续改用对称算法加密通信

再发送Encrypted Handshake Message,把之前发送的数据做一个摘要,再用对称密钥加密,让服务端做验证。

image-20231007154323183

若为RSA密钥协商算法,这里客户端会生成一个随机数pre-master,并用服务端的RSA公钥加密该随机数,发送Client Key Exchange消息将加密的pre-master发送过去。服务端收到后,⽤RSA私钥解密,得到客户端发来的随机数pre-master,然后用 客户端随机数 + 服务端随机数 + pre-master 得到共享密钥,后续一样。

第四次握手

服务端也会发Change Cipher SpecEncrypted Handshake Message消息,如果双⽅都验证加密和解密没问题,那么握⼿正式完成。接下来可以正常收发加密的 HTTP 请求和响应了

RSA Diff ECDHE

使用RSA密钥协商算法的一个问题就是不支持前向保密(forward security),一旦服务端的私钥泄露(攻击者用来解密pre-master),过去被第三方截获的所有TLS通讯密文都会被破解

前向保密:用来产生会话密钥(session key)的长期密钥(long-term key)泄露出去,不会造成之前通讯时使用的会话密钥(session key)的泄露,也就不会暴露以前的通讯内容

下面复习一下Diffie-Hellman密钥协商算法

image-20231007173419766

客户端和服务端互相传递自己的公钥,双方根据各自持有的密钥能够算出一个相同的值,这个值用于后面对称加密使用。

由于每⼀次对称加密密钥都是实时⽣成的,因此能够保证前向保密。

DH是非对称加密算法,主要用于密钥交换,基于离散对数问题。

image-20231007174908843

底数a和模数p是离散对数的公共参数,b是真数,i是对数。由对数算出真数很容易,但由真数反推对数却很困难。

当p为很大的指数时,求解对数i就是一个数学难题。

准备:Alice和Bob协商好一个大素数q和q的一个本原元 α, 1< α <q , q 和 α公开

image-20231007175319515

为了安全通信,每次双方都重新生成随机数,因此也叫DHE算法(E:ephermeral临时性的)

为了提升DH算法的性能,出现了现在⼴泛⽤于密钥交换算法 —— ECDHE 算法。 ECDHE 算法是在 DHE 算法的基础上利⽤了 ECC 椭圆曲线特性,可以⽤更少的计算量计算出公钥,以及最终的会 话密钥。

CA

一个数字证书通常包含如下内容:

  • 公钥

  • 证书持有者信息

  • 证书认证机构CA的信息

  • CA对证书的数字签名及使用的算法

  • 证书的有效期

  • 一些额外信息

证书用来认证公钥持有者的身份,以防第三方冒充

image-20231007165357785

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

image-20231007170008791

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

image-20231007170303726

之所以存在中间证书,是为了确保根证书的绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。

Cer Transfer

相同安全强度下,ECC密钥⻓度⽐RSA短的多,因此服务端的证书应该选择椭圆曲线证书,以减少证书大小,更便于传输。

Cer Verfify

客户端在验证证书时,会⾛证书链逐级验证,验证的过程不仅需要⽤CA公钥验证证书签名,⽽且为了知道证书是否被CA吊销,客户端还会再去访问CA中心,下载CRL或者OCSP数据,以此确认证书的有效性。

CRL

CRL(Certificate Revocation List)证书吊销列表,这个列表是由 CA 定期更新,列表内容都是被撤销信任的证书序号,如果服务器的证书在此列表,就认为证书已经失效,不在的话,则认为证书是有效的。

image-20231007155842162

CRL问题也很明显

  • 实时性差。若一个证书刚被吊销,CRL还没来得及更新,客户端就已经信任了这个证书

  • CRL传输时延。随着吊销证书增多,CRL这个列表会越来越大,下载速度就会慢,客户端还得遍历一个大列表

OSCP

OSCP(Online Certificate Status Protocol)在线证书状态协议,用于查询证书的有效性,客户端向CA发送查询请求,CA返回证书的有效状态

image-20231007160523208

通常是服务端向CA周期性地查询证书状态,获得⼀个带有时间戳和签名的响应结果并缓存它。当有客户端发起连接请求时,服务端把CA的响应结果在TLS握手

过程发送给客户端。由于有签名的存在,服务端无法篡改,客户端就能得知证书是否被吊销,这样客户端就不用去查询了。

image-20231007160810112

Last updated

Was this helpful?