我们知道,HTTP传输数据是不安全的

  • 使用明文传输数据,HTTP 的所有信息都暴露在了光天化日之下
  • 不验证通信方的身份,因此有可能遭遇伪装请求
  • 无法证明报⽂的完整性,内容有可能已遭篡改

因此HTTPS正是为了解决上述问题。HTTPS 相比 HTTP 协议多⼀个 TLS 协议握手过程,目的是为了通过非对称加密握手交换出对称加密密钥,接着后续传输的应用数据都得使用对称加密密钥来加密、解密
微信截图_20210804220707.png

加密传输

为了解决明文传输,HTTPS 采用的是对称加密和非对称加密结合的混合加密方式:

  • 在通信建立前采用非对称加密的方式交换会话秘钥
  • 在通信过程中全部使用对称加密的会话秘钥的方式加密明文数据

微信截图_20210805224937.png

数字签名

为了保证消息完整性问题,可以通过数字签名解决。将消息或消息的摘要通过加密算法加密后的密文作为该消息的数字签名
微信截图_20210805225205.png
客户端在发送明⽂之前会通过摘要算法算出明⽂的 “指纹”,发送的时候把 “指纹” 和明文⼀同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过⽐较客户端携带的 “指纹” 和当前算出的 “指纹” 做比较,若相同,说明数据是完整的。

数字证书

数字证书的作用是用来认证公钥持有者的身份,以防止第三方进行冒充。说简单些,证书就是用来告诉客户端,该服务端是否是合法的,因为只有证书合法,才代表服务端身份是可信的。

为了让服务端的公钥被⼤家信任,服务端的证书都是由具有权威性和公正性的第三方机构(Certificate Authority)发放的,CA就是网络世界的公安局、公证中心,具有极高的可信度,所以由它来给各个公钥签名,信任的⼀方签发的证书, 那必然证书也是被信任的。

数字证书通常包含了:

  • 证书所有人的信息
  • 证书所有人的公钥
  • 认证机构的信息
  • CA对这份证书的数字签名及使用的算法
  • 其他额外信息

特别的,为了防止证书的伪造和篡改,还需要加入数字签名
微信截图_20210804223542.png

TLS四次握手

传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的,在将 TLS 证书部署服务端时,证书文件中包含⼀对公私钥,其中公钥会在 TLS 握⼿阶段传递给客户端,私钥则⼀直留在服务端,⼀定要确保私钥不能被窃取

在 RSA 密钥协商算法中,客户端会⽣成随机密钥,并使用服务端的公钥加密后再传给服务端。根据非对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双⽅就得到了相同的密钥,再用它加密应用消息。

第一次握手

客户端首先会发⼀个 Client Hello 消息给服务端,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,以及生成的客户端随机数(Client Random),这个随机数会被服务端保留,它是⽣成对称加密密钥的材料之⼀。
微信截图_20210804224709.png

第二次握手

当服务端收到客户端的 Client Hello 消息后,会确认 TLS 版本号是否⽀持,和从密码套件列表中选择⼀个密码套件,以及生成服务端随机数(Server Random)。接着,返回Server Hello 消息,消息里面有服务器确认的 TLS 版本号,也给出了随机数(Server Random),及选择的密码套件。
微信截图_20210804225008.png

接着,服务端为了证明自己的身份,会发送 Server Certificate 给客户端,这个消息里面含有服务端的数字证书。
微信截图_20210804225503.png

最后,服务端发了 Server Hello Done 消息,目的是告诉客户端,我已经把该给你的东西都给你了。
微信截图_20210804225639.png

第三次握手

客户端获取证书后,根据证书的数字签名校验证书的合法性,接着获取服务端公钥。客户端就会⽣成⼀个新的随机数 (pre-master),并用服务器的 RSA 公钥加密该随机数,通过 Change Cipher Key Exchange 消息传给服务端。
微信截图_20210804230624.png
服务端收到后,用 RSA 私钥解密,得到客户端发来的随机数 (pre-master)。至此,客户端和服务端双⽅都共享了三个随机数,分别是 Client Random、Server Random、pre-master。于是,双⽅根据已经得到的三个随机数,生成会话密钥(Master Secret),它是对称密钥,用于对后续的 HTTP请求/响应的数据加解密。

生成完会话密钥后,然后客户端发⼀个 Change Cipher Spec,告诉服务端开始使用加密方式发送消息。
微信截图_20210804231144.png

然后,客户端再发⼀个 Encrypted Handshake Message(Finishd)消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密⼀下,让服务器做个验证,验证加密通信是否可⽤和之前握⼿信息是否有被中途篡改过。
微信截图_20210804231310.png

第四次握手

服务器也是同样的操作,发 Change Cipher Spec 和 Encrypted Handshake Message 消息,如果双方都验证加密和解密没问题,那么握⼿正式完成。后续可以通过会话秘钥进行加密HTTP请求和响应。

微信截图_20210804234528.png