网络编程(十)图解HTTPS

图解HTTPS

一、HTTPS

安全问题

我们先来看下数据在互联网上数据传递可能会出现的三个比较有代表性的问题,其实后面提到的所有方法,都是围绕解决这三个问题而提出来的。

窃听

image-20211226140025006

伪造

image-20211226140054792

否认

image-20211226140127170

解决方案

对称密钥加密

假设 A 正在通过互联网向 B 发送数据,如果不对数据进行加密,数据就可能被恶意的第三者 X 看到

因此,需要保密的数据需要进行加密再发送

image-20211226140238587

  • 用将数据进行加密,使其成为密文
  • 把密文发送给 B
  • B 使用密钥解密从 A 收到的密文,这样就能得到原始数据
  • 因为是加密数据,即使它被恶意的第三方截获也是安全的

“对称密钥加密” 一个很重要的特点就是使用相同的密钥进行加密和解密

image-20211226140332061

回到刚刚那个场景,假设 B 是没有解密钥匙的,所以 A 需要通过互联网将钥匙发送给 B

  • 但是 X 也有可能看到这个钥匙
  • 因此,X 也可以通过这个钥匙来解密密文

上面这个场景就会引出一个新问题,这个问题被称为 “钥匙交付问题”,那怎么解决这个问题?

公开密钥加密

为了解决上面的 “钥匙交付问题”,我们这里引入一个新的方法 —— “公开密钥加密”,下图是 “公开密钥加密” 的主要特点

image-20211226140446037

  • 用于加密的密钥被称为“公钥”,用于解密的密钥被称为“私钥”
  • 跟 “对称密钥加密” 相比,公开密钥加密往往需要更多的时间用于加密和解密

我们来看看 “公开密钥加密” 的一整个过程

image-20211226140544106

接收方 B 创建一个公钥和一个私钥,公钥被发送给 A

image-20211226140615591

  1. A 使用从 B 收到的公钥加密数据,将密文发送给 B
  2. B 使用私钥解密从 A 接收到的密文,得到原始数据

在这个过程中

  • 密文和公钥也可能被恶意第三方 X 截获
  • 但是私钥是 B 保存的,X 无法获取到,自然没有办法解密密文
  • 这样就很好的解决了 “钥匙交付问题”

公开密钥加密的问题

  1. 加密和解密都需要耗费时间,有一种叫 “混合加密” 的方法可以解决这个问题
  2. 公开密钥的可靠性

混合加密

image-20211226140740479

混合密钥加密分为两个步骤

  1. 通过公开密钥加密传递密钥
  2. 通过速度更快的对称密钥加密方法传递数据

中间人攻击

为了更好地理解公开密钥加密的可靠性问题,我们回到传递公钥的场景

image-20211226141314756

A 拿到的其实是 X 发送给他的伪造公钥,但是 A 无法察觉

image-20211226141342988

最后,X 用他自己的密钥加密响应数据,并发送给 A,就这样,虽然 AB 双方能顺利完成通信,但是恶意的第三方 X 能看到解密后的请求数据和响应数据,而 AB 双方则毫不知情。

这种通过秘密替换公钥窃取数据的方法被称为“中间人攻击”,问题的根源在于 A 无法确认他们收到的公钥是否由 B 方创建。怎么避免中间人攻击呢?我们放到数字证书那节再探讨,接下来再讲解一点前置知识

消息鉴别码

消息鉴别码在英文中被称为 MACMAC 可以理解为密钥和密文组成的字符串的哈希值

image-20211226141435294

消息鉴别码虽然可以解决伪造问题,但是仍然无法避免 否认 问题

数字签名

为了解决这个 否认 问题,我们接下来看看 “数字签名” 方法

image-20211226141514346

数字证书

虽然上面的方法已经能避免 窃听伪造否认 等问题,但是现在还是没办法避免“中间人攻击”,因为我们还是没办法验证公钥的所有者,因此我们需要 “数字证书” 系统来验证公钥的所有者。

接下来,先看看数字证书申请的过程,我们将数字证书认证机构(Certificate Authority)我们称之为 CA

image-20211226141732985

现在 B 已经申请到一个数字证书了,那么怎么使用数字证书来检验公钥 PB 是属于 B 呢

image-20211226141753503

现在可以验证 PB 是属于 B 的,但是怎么验证 PC 是属于受信任的 CA 的呢

image-20211226141812983

事实上,认证机构形成一个树形结构,高级别的权威机构为较低级别的机构创建证书,那就是说,如果要验证的话,就是一级一级向上认证,信任链条的最终是Root CA,他采用自签名,对他的签名是无条件的信任。

image-20211226141833606

HTTPS

完全理解上面说的东西之后,就能够很容易理解 HTTPS,它采用的就是上面说的 “混合加密” + “数字证书” 两种技术,来保证整个通信过程的安全可靠。

HTTPS 做的事情其实就是在传输层跟应用层之间加了一层 SSL/TLS,用于对 TCP 传输内容的加密和解密

image-20211226141906704

下图我们再看一下详细的工作流程

image-20211226141934829

二、SSL/TLS

概览

在构建网络应用,特别是暴露在 internet 中的应用时,通常都会使用 SSL/TLS 协议增强数据传输的安全性,其结构如下:

TLS协议结构

SSL / TLS 以及 SSL / TLS 握手的概念

SSL 和 TLS 协议可以为通信双方提供识别和认证通道,从而保证通信的机密性和数据完整性。TLS 协议是从Netscape SSL 3.0协议演变而来的,不过这两种协议并不兼容,SSL 已经逐渐被 TLS 取代,所以下文就以 TLS 指代安全层。 TLS 握手是启动 HTTPS 通信的过程,类似于 TCP 建立连接时的三次握手。 在 TLS 握手的过程中,通信双方交换消息以相互验证,相互确认,并确立它们所要使用的加密算法以及会话密钥 (用于对称加密的密钥)。可以说,TLS 握手是 HTTPS 通信的基础部分。

TLS 握手过程中发生了什么

我们已经知道 TLS 握手的目的是建立安全连接,那么通信双方在这个过程中究竟干了什么呢?下面就是答案:

  • 商定双方通信所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
  • 确定双方所要使用的密码组合;
  • 客户端通过服务器的公钥和数字证书上的数字签名验证服务端的身份;
  • 生成会话密钥,该密钥将用于握手结束后的对称加密。

TLS 握手详细过程

下面来看 TLS 握手的详细过程 :

2771952479-5e1ad3408e724

SSL / TLS 握手详细过程

  1. “client hello”消息:客户端通过发送”client hello”消息向服务器发起握手请求,该消息包含了客户端所支持的 TLS 版本和密码组合以供服务器进行选择,还有一个”client random”随机字符串。
  2. “server hello”消息:服务器发送”server hello”消息对客户端进行回应,该消息包含了数字证书,服务器选择的密码组合和”server random”随机字符串。
  3. 验证:客户端对服务器发来的证书进行验证,确保对方的合法身份,验证过程可以细化为以下几个步骤:
    1. 检查数字签名
    2. 验证证书链 (这个概念下面会进行说明)
    3. 检查证书的有效期
    4. 检查证书的撤回状态 (撤回代表证书已失效)
  4. “premaster secret”字符串:客户端向服务器发送另一个随机字符串”premaster secret (预主密钥)”,这个字符串是经过服务器的公钥加密过的,只有对应的私钥才能解密。
  5. 使用私钥:服务器使用私钥解密”premaster secret”。
  6. 生成共享密钥:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥 KEY
  7. 客户端就绪:客户端发送经过共享密钥 KEY加密过的”finished”信号。
  8. 服务器就绪:服务器发送经过共享密钥 KEY加密过的”finished”信号。
  9. 达成安全通信:握手完成,双方使用对称加密进行安全通信。

reference

  • https://juejin.cn/post/6844903764399243278
  • https://segmentfault.com/a/1190000021559557
  • https://neotan.github.io/ssl-tls/
  • https://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
  • https://tinychen.com/20200602-encryption-intro