HTTPS 加密过程详解

我们常说 HTTPS 比 HTTP 安全,那么它到底安全在哪?它的实现原理又是怎么样的?在本篇文章中我们一起探究下。

加密内容

HTTPS encrypts all message contents, including the HTTP headers and the request/response data. )

上面是 Wiki 上对 HTTPS 加密内容的介绍,HTTPS 加密包括请求头、请求数据在内的所有信息,暴露在外的只有请求方的 IP 地址和服务器的 IP 地址(地址如果被加密无法路由),攻击者仅仅知道在双方之间建立了连接。

实际上我们可以这么理解,我们知道 TCP/IP 五层模型从高到低依次为应用层、传输层、网络层、数据链路层以及物理层。而 HTTPS = HTTP + SSL,SSL 位于应用层与传输层之前,更确切的说是在传输层进行工作,当 SSL 开始工作时,请求数据已经从应用层流动过来了,自然可以加密包括请求头在内的一切信息了。

当然,必须得明文目的主机以及端口,不然请求也路由不过去。

加密原理及实现

现在我们来大致了解一下 HTTPS 的加密原理及实现。

当一个 HTTPS 请求从浏览器发出,浏览器发现此为 HTTPS 请求,会在发送的信息中带上支持的 SSL 版本或者 TLS 版本。

public enum TlsVersion {
TLS_1_3("TLSv1.3"), // 2016.
TLS_1_2("TLSv1.2"), // 2008.
TLS_1_1("TLSv1.1"), // 2006.
TLS_1_0("TLSv1"), // 1999.
SSL_3_0("SSLv3"), // 1996.
;
final String javaName;
}

OkHttp 中表示 TLS 协议不同版本的 enum

服务端除了正常的数据返回外,还会返回确认使用的加密通信协议版本以及加密随机数证书。加密通信版本我们可以理解,后面的加密随机数和整数又是为什么要返回呢?

我们先看看数据传输过程中的加密过程。

加密

假设现在有一个客户端和一个服务端进行点对点通信,客户端为了防止被第三方中间截取自己的信息(比如登陆密码),通过任意加密算法将数据进行加密,连同解密的密钥一起发送给服务端。

这中间存在一个很明显的问题,密钥仍然是明文的,第三方截取到请求自然也能拿到明文密钥,等同于没加密。

上述加密方式被称为对称加密,即加密解密只使用一个唯一密钥,对称加密的有点在于快,缺点在于不安全,常见对称加密算法有 AES、DES等。

为了解决上述问题,我们可以采用了非对称加密,即每个客户端只持有公钥,服务端拥有密钥。非对称加密的问题在于速度慢。

证书

既然我们打算采用非对称加密,那么我们首先要获取到公钥,即在建立连接之初,客户端首先要从服务端获取到公钥。

公钥在传输的过程中是可能会被第三方篡改的,最终客户端拿到一个假的公钥。

为了防止出现这种情况,就有了数字证书校验。这回答了我们开头的疑惑,为什么要返回证书。

服务端在返回的证书中,会包含这次非对称加密的公钥。

接着进行证书合法性校验:

  • 浏览器从服务器拿到证书。证书上有服务器的公钥和 CA 机构打上的数字签名。

  • 拿到证书后验证其数字签名。具体就是,根据证书上写的 CA 签发机构,在浏览器内置的根证书里找到对应的公钥,用此公钥解开数字签名,得到摘要(digest,证书内容的 hash 值),据此验证证书的合法性。

HTTPS 接下来的加密过程:

  1. 验证完合法性后,在证书里取出服务器的公钥。
  2. 浏览器生成对称密钥
  3. 使用服务器公钥和随机数对该对称密钥加密,发回给服务器。
  4. 服务器使用私钥解密,得到对称密钥。
  5. 服务器使用该对称密钥加密后续 http 数据。使用对称密钥加密是因为比非对称加密高效。

参考资料

文章作者: yPhantom
文章链接: https://guoyuxiang.cn/2021/04/13/process-of-https-encryption/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Life Note