22 TLS握手

Posted by CodingWithAlice on April 28, 2021

22 TLS握手

写的比较好的博文:深入理解HTTPS原理、过程与实践

  • 总结

    1、HTTPS 协议会 先与服务器执行 TCP 握手,然后执行 TLS 握手,才能建立安全连接

    2、握手的目标是安全地交换 对称密钥,需要三个随机数,第三个随机数 Pre-Master 必须加密传输,绝对不能让黑客破解

    3、Hello 消息交换随机数,Key Exchange 消息交换 Pre-Master

    4、Change Cipher Spec 之前传输的都是明文,之后都是对称密钥加密的密文

在 HTTP 协议里,建立连接后,浏览器会立即发送请求报文。但现在是 HTTPS 协议,它需要再用另外一个 握手 过程,在 TCP 上建立安全连接,之后才是收发 HTTP 报文

TLS 协议的组成

  • 定义

    由几个不同职责的模块组成,比较常用的有记录协议、警报协议、握手协议、变更密码规范协议等

  • 组成模块

    • 1、记录协议(Record Protocol)

      规定了 TLS 收发数据的 基本单位:记录(record)

      它有点像是 TCP 里的 segment,所有的其他子协议都需要通过记录协议发出

      多个记录数据可以在一个 TCP 包里一次性发出,也并不需要像 TCP 那样返回 ACK

    • 2、警报协议(Alert Protocol)

      职责是向对方发出警报信息,有点像是 HTTP 协议里的状态码

      例子:

      • protocol_version 就是不支持旧版本
      • bad_certificate 就是证书有问题,收到警报后另一方可以选择继续,也可以立即终止连接
    • 3、握手协议(Handshake Protocol)

      比 TCP 的 SYN/ACK 复杂的多,浏览器和服务器会在握手过程中协商 TLS 版本号、随机数、密码套件等 信息,然后交换证书和密钥参数,最终双方协商得到会话密钥,用于后续的混合加密系统

    • 4、变更密码规范协议(Change Cipher Spec Protocol)

      它非常简单,就是一个通知,告诉对方,后续的数据都将使用加密保护。那么反过来,在它之前,数据都是明文的

握手过程

image-20210428101402152

解析一下:

1、Client Hello:有客户端的版本号、支持的密码套件,还有一个随机数Client Random,用于后续生成会话密钥

2、Server Hello:把版本号对一下,也给出一个随机数 Server Random,然后从客户端的列表里选一个作为本次通信使用的密码套件 ECDHE 算法

3、服务器为了证明自己的身份,就把证书也发给了客户端 Server Certificate

4、Server Key Exchange:给出 公钥 用来实现密钥交换算法,再加上自己的 私钥签名认证

5、Server Hello Done:打招呼完毕

– 第一个消息往返就结束了(两个 TCP 包)–

结果:客户端和服务器通过明文共享了三个信息 Client RandomServer RandomServer Params

6、客户端开始走 证书链逐级验证,确认证书的真实性,再用证书公钥验证签名,就确认了服务器的身份

7、Client Key Exchange:客户端按照密码套件的要求,也生成一个 公钥

– 客户端和服务器手里都拿到了密钥交换算法的两个参数(Client ParamsServer Params),用 ECDHE 算法计算得到随机数Pre-Master –> 现在客户端和服务器都有三个随机数了,有了这三个随机数,会利用算法扩展更多的密钥,避免使用一个密钥 –

8、Change Cipher Spec + Finished:客户端发送消息,把之前所有发送的数据 做个摘要,再加密一下,让服务器做个验证 –> 后续就使用 对称加密算法 通信了

9、Change Cipher SpecFinished:服务器也是同样的操作,双方都验证加密解密 OK,握手正式结束,后面就收发被加密的 HTTP 请求和响应了

注意:

  • 使用 ECDHE 实现密钥交换,而不是 RSA,所以会在服务器端发出Server Key Exchange消息。

  • 因为使用了 ECDHE,客户端可以 不用等到服务器发回Finished确认握手完毕,立即就发出 HTTP 报文,省去了一个消息往返的时间浪费。

    这个叫TLS False Start,意思就是抢跑,和TCP Fast Open有点像,都是不等连接完全建立就提前发应用数据,提高传输的效率。