HTTPS 原理

292 阅读4分钟

HTTPS 是什么

HTTPS 即 HTTP over SSL/TLS。 HTTP 是建立在 TCP 之上的,而 HTTPS 则是在 HTTP 和 TCP 中间加上 SSL/TLS 层。

HTTPS 的作用

HTTP 的传输都是明文的,这在安全上造成了极大的隐患。HTTPS 就是把原来的明文传输变成密文传输。

对称加密和非对称加密

既然 HTTPS 需要传输密文,这就涉及到客户端和服务端的加解密。

加密算法可以分为对称加密非对称加密

对称加密的特点是只有一个密钥,加解密都需要这个密钥。

非对称加密的特点是有两个密钥——公钥和私钥,加解密的过程是单向的,即使用私钥加密只有公钥能解密,同样使用公钥加密就只能使用私钥解密。

这里需要提及的是,使用私钥加密又被称为签名,客户端可以使用公钥来验证是否由服务端发送的且没有被篡改的数据。

需要注意的是,对称加密的效率比非对称加密的效率要高(即加密速度上,对称加密要快)。

HTTPS 加密方案选择

现实生活中,双方可以口头约定只有双方知道的密钥,使用对称加密即可。

而互联网是开放的,同时也意味着所有的信息都面临着被篡改或监听的风险,因此客户端和服务端在通信前很难直接约定一个只有双方知道的密钥。

因此只能使用非对称加密的方式,即服务端生成自己的公钥和私钥,私钥自己存储,公钥公布出去,这样任意客户端都可以使用服务端的公钥加密需要传输的数据。

该方案的问题是,如何保证服务端公布的公钥没被篡改,因为公钥的公布也是通过互联网环境的,这又回到了最原始的问题。

这时就需要一个第三方服务来背书即 CA 机构。

CA (Catificate Authority)

CA 机构首先给服务端颁发证书。

而计算机系统在安装时就已经保存了各个 CA 的根证书,也就是说计算机本身是有能力确认服务端发送的证书是否合法,也即服务端的公钥是否可信。

由此就完成了一个完美的闭环,最终的安全隐患落到了计算机系统身上,而这就是 windows/linux/macos 等系统厂商需要做的事了。

SSL/TSL 握手过程

前文提过,非对称加密效率较对称加密底,因此 HTTPS 每次连接时只使用非对称加密来协商一个对称加密密钥 KEY,后期的数据传输则使用对称加密来完成。

下面就来详细讲解下该对称加密密钥的协商过程,也即 SSL/TSL 握手过程。

HTTPS 请求在发送前会先建立 SSL/TSL 链接:

  1. 【客户端】发送 client hello 信息,该信息包含:

    1. 【客户端】支持的 TLS 版本
    2. 【客户端】支持的加密算法
    3. 【客户端】生成的 client random 字符串
  2. 【服务端】发送 server hello 信息,该信息包含:

    1. 数字证书(包含公钥)
    2. 【服务端】支持的加密算法
    3. 【服务端】生成的 server random 字符串
  3. 【客户端】验证证书,生成随机 premaster secret, 并向服务端发送使用公钥加密过的 premaster secret

  4. 【服务端】使用私钥解密得到 premaster secret

  5. 【客户端】使用 client random, server random, premaster secret 生成对称加密密钥 KEY, 并发送 finished 信号

  6. 【服务端】使用 client random, server random, premaster secret 生成对称加密密钥 KEY, 并发送 finished 信号

至此,双方已经协商出对称加密密钥,后期的数据传输则可以使用该密钥进行。

之所以需要 clinet random 和 server random 是因为双方互不信任能否产生有效随机数,因此双方各提供一个以增加可信度。

以上传输的风险最终会落到 premaster secret 上,如果服务端私钥泄漏则意味着加密密钥 KEY 泄漏,之前通过 KEY 完成的通信就面临泄漏的风险。

这里再介绍一下 Diffie-Hellman 算法。该算法的特点是,双方各自只用交换各自计算出的数,就可自行计算出相同的 KEY,简单的描述一下即:

  1. 【客户端】本地生成随机数 a,经过特定算法生成 a'
  2. 【服务端】本地生成随机数 b,记过特定算法生成 b'
  3. 【客户端】和【服务端】分别交换 a' 和 b'
  4. 【客户端】通过 a 和 b',经过特定算法计算出 KEY
  5. 【服务端】通过 b 和 a',经过特定算法计算出 KEY

该算法的特点是即使第三者获取 a' 和 b' 也计算不出 KEY 值,因此上述传递 client random, server random, premaster secret 的过程则可改为传递 a'b', 这样即使服务端私钥泄漏,也不会影响之前传输数据的安全。