技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTNET

看图学 HTTPS

所属馆藏
NET Protocol
文件格式
Markdown
原始路径
NET Protocol/27-看图学HTTPS
本文目录15 个章节
  1. 前言
  2. 正文
  3. HTTP 是什么样的?
  4. 加密可以解决问题吗?
  5. 多个客户端怎么办?
  6. 对称加密密钥如何传输?
  7. 非对称加密
  8. 中间人攻击
  9. 第三方认证:证书与数字签名
  10. 为什么要有数字签名?
  11. 对称加密与 TLS 会话密钥
  12. 整体流程图
  13. HTTPS 的性能影响
  14. 总结
  15. 参考资料

看图学 HTTPS

Category(分类): NET Protocol Status: 未知

前言

之前说到 HTTPS,我的概念中只有“更安全”和“需要服务器配置证书”,但对 HTTPS 为什么更安全、整套流程如何实现没有具体概念。因此,本文通过一幅幅流程图,对 HTTP 到 HTTPS 的演变过程进行入门介绍。

本文中的图片和示意流程主要用于帮助理解。真实 TLS 的握手过程会根据 TLS 版本、密码套件、会话恢复和实现方式有所不同,不能把所有示意图直接当作 TLS 1.3 的完整报文流程。

本文也会同步到个人网站

正文

HTTP 是什么样的?

HTTP 属于应用层协议。HTTP/1.1 通常运行在 TCP 之上,TCP 负责可靠的字节流传输,IP 负责寻址和路由;HTTP/2 也通常运行在 TCP 之上,而 HTTP/3 则运行在 QUIC 之上。HTTP 主要规定请求方法、状态码、首部和内容等语义。

最简单的 HTTP 通信过程如下:

HTTP 请求与响应示意图

客户端发出请求,服务器返回响应。在直接使用 http:// 时,HTTP 内容通常以明文形式传输,网络中的中间人可能读取、篡改或伪造数据,造成信息泄露和请求劫持。

HTTP 本身不提供加密和身份认证,但 HTTP 可以运行在 TLS 之上,这就是 HTTPS。

加密可以解决问题吗?

因为明文传输不安全,一个自然的想法是在发送前对数据进行加密:

对称加密传输示意图

这种加密方式叫作对称加密。对称加密使用同一个秘密密钥进行加密和解密。实际 TLS 常用 AES-GCM、ChaCha20-Poly1305 等 AEAD 算法,它们同时提供机密性和完整性保护。

但仅仅“加密”还不够,还需要解决密钥如何安全地交给通信双方,以及客户端如何确认自己连接的确实是目标服务器。

多个客户端怎么办?

假设服务器和所有客户端都使用同一个密钥:

所有客户端共用同一密钥的风险

这种方式显然不合理:一旦某个客户端的密钥泄露,其他客户端的通信也可能受到影响。实际系统通常不会让所有用户长期共用同一个应用数据密钥,而是为连接建立独立的会话密钥。

如果为每一个客户端或每一条连接使用不同的密钥,可以降低密钥泄露的影响范围:

不同客户端使用不同密钥

但新的问题是:客户端和服务器如何安全地得到这把会话密钥?

对称加密密钥如何传输?

如果一端生成对称密钥,再通过普通 HTTP 直接传输给另一端:

通过明文传输对称密钥的风险

中间人就可能截获密钥并解密后续数据。对称密钥再用另一个没有安全传输渠道的对称密钥加密,会陷入“新的密钥如何传输”的循环。

解决这个问题不能只依靠不断套用对称加密,而需要使用经过身份认证的密钥协商机制。早期 TLS 可以使用 RSA 密钥交换,现代 TLS 1.3 通常使用临时 Diffie-Hellman(ECDHE)协商共享秘密。

非对称加密

非对称密码学使用一对密钥:公钥私钥。公钥可以公开,私钥必须由持有者妥善保管。

以 RSA 为例,公钥加密的内容通常由对应私钥解密。但现代密码学还要区分另一种用途:

  • 公钥加密、私钥解密:主要用于机密性;
  • 私钥签名、公钥验证:主要用于身份认证和完整性。

“私钥加密、公钥解密”是对数字签名的简化说法,不应当把数字签名当成普通加密。RSA 只是非对称密码学的一类算法,现代 TLS 的密钥协商还常使用基于椭圆曲线的 ECDHE。

非对称加密示意图

在传输服务器公钥的过程中,中间人确实可以看到公钥。看到公钥本身并不危险,因为公钥本来就可以公开;真正的问题是客户端如何确认拿到的公钥属于目标服务器,而不是属于中间人。

中间人攻击

MITM 是 Man-in-the-Middle Attack 的缩写,中文称为中间人攻击。

如果客户端只接收网络上传来的公钥,而不验证公钥的身份,中间人可以把服务器公钥替换成自己的公钥:

中间人替换服务器公钥

客户端误以为这是服务器的公钥,并使用它加密数据。中间人就可以用自己的私钥解密数据,再使用真正服务器的公钥重新加密并转发,客户端和服务器都可能意识不到通信已经被监听。

因此,HTTPS 需要在密钥协商之外增加服务器身份认证。

第三方认证:证书与数字签名

在 HTTPS 中,服务器通常通过 X.509 证书 + 数字签名 向客户端证明自己的身份。

证书与数字签名示意图

证书不是简单的“把网站信息加密后发给客户端”。一张证书通常包含:

  • 服务器公钥;
  • 域名身份信息,现代证书主要通过 Subject Alternative Name(SAN)表示;
  • 有效期;
  • 证书序列号和签发者;
  • Key Usage、Extended Key Usage 等扩展;
  • CA 对证书内容的数字签名。

CA 会对待签名证书内容计算摘要,然后使用 CA 私钥生成数字签名。这里不能使用 MD5 作为现代安全签名算法,MD5 已经不适合安全用途,实际系统通常使用 SHA-256 等安全哈希算法配合数字签名算法。

数字证书可以简化理解为:

证书 = 服务器身份信息 + 服务器公钥 + CA 数字签名 + 其他扩展字段

如果中间人拦截证书并替换服务器公钥,由于没有 CA 的私钥,通常无法为修改后的证书生成有效的 CA 签名,客户端验证证书链时就会失败。

证书被篡改后的验证失败示意图

浏览器、操作系统或应用程序会预置一些信任根证书。客户端不是“解密证书”,而是使用信任库中的 CA 公钥验证签名,并检查:

  1. 证书链能否连接到本地信任的根 CA;
  2. 当前访问的域名是否匹配证书的 SAN;
  3. 证书是否在有效期内;
  4. 证书是否允许用于服务器身份认证;
  5. 证书是否被撤销或被本地安全策略禁止使用。

服务器通常发送终端证书和中间 CA 证书,根证书一般已经在客户端信任库中,不需要服务器重复发送。

为什么要有数字签名?

CA 是一个可以为多个网站签发证书的机构。中间人也可以申请证书,但 CA 必须验证申请者对域名的控制权或组织身份,不能只因为“申请了”就签发任意域名的证书。

如果没有 CA 的数字签名,任何人都可以声称某个公钥属于某个网站,客户端无法判断证书内容是否真的得到可信机构认可:

为什么需要数字签名

没有数字签名时的身份伪造风险

数字签名的作用不是隐藏证书内容,而是证明证书内容确实由对应 CA 签发,并且在签发后没有被修改。公钥本身可以公开,证书也可以被任何人读取,但攻击者不能仅凭读取证书就伪造有效签名。

如果用户手动安装了攻击者控制的根证书,或者操作系统、浏览器的信任库被修改,攻击者就可能重新建立一条客户端信任的证书链。因此,不要随便安装来源不明的根证书,也不要忽略浏览器的证书错误。

对称加密与 TLS 会话密钥

在较早的 TLS 1.2 RSA 密钥交换示意中,客户端可能生成 premaster secret,并使用服务器证书中的 RSA 公钥加密后发送给服务器,双方再从中派生会话密钥:

旧式 RSA 密钥交换与应用数据示意图

但这不是现代 TLS 1.3 的完整流程。TLS 1.3 通常使用 ECDHE:

  1. 客户端在 ClientHello 中发送支持的版本、密码套件、随机数和密钥交换参数;
  2. 服务器在 ServerHello 中发送自己的密钥交换参数,并发送证书和 CertificateVerify
  3. 客户端验证证书链、域名和服务器的握手签名;
  4. 客户端和服务器分别计算相同的 ECDHE 共享秘密;
  5. 双方通过 HKDF 派生 TLS 记录层使用的会话密钥;
  6. 后续 Application Data 使用 AES-GCM 或 ChaCha20-Poly1305 等对称 AEAD 算法传输。

最终的应用数据密钥通常不会直接在网络上传输。临时 ECDHE 还可以提供前向保密:即使服务器长期证书私钥日后泄露,也不能直接解密过去捕获的 TLS 1.3 1-RTT 会话数据。

整体流程图

更准确的表达是:

HTTPS = HTTP over TLS

TLS 位于 HTTP 和传输层之间。对于 HTTP/1.1 和 HTTP/2,底层通常是 TCP;HTTP/3 则运行在 QUIC 之上。

HTTPS 整体流程示意图

一次新的 TLS 1.3 HTTPS 连接大致包含以下过程:

客户端                                  服务器
  | -------- ClientHello --------------> |
  | <------- ServerHello --------------- |
  | <------- Certificate --------------- |
  | <------- CertificateVerify --------- |
  | <------- Finished ------------------ |
  | -------- Finished ----------------> |
  | <====== 加密的 HTTP Application Data ======> |

实际 TLS 1.3 报文会根据密钥交换、客户端认证、会话恢复和实现方式变化。TLS 1.2 的握手流程也与 TLS 1.3 不同,不能把一张简化图片当成所有版本的固定流程。

TLS 完整握手流程参考图

HTTPS 的性能影响

HTTPS 会增加一定的握手和计算开销,但不能简单说“HTTPS 一定很慢”:

  • TCP 三次握手通常按约 1 个 RTT 估算;
  • TLS 1.2 完整握手通常还需要约 2 个 RTT;
  • TLS 1.3 完整握手通常还需要约 1 个 RTT;
  • 持久连接可以复用已经建立的 TCP + TLS 连接;
  • TLS 会话恢复可以减少握手往返;
  • TLS 1.3 0-RTT 可以发送早期数据,但存在重放风险,只适合安全幂等的操作;
  • 对称加密通常比非对称运算高效,现代 CPU 也常有硬件加速。

HTTP/2 通常通过 TLS 的 ALPN 在握手阶段协商。HTTPS 负责 TLS 安全传输,HTTP/2 负责二进制分帧和多路复用,它们属于不同层次,不能把“HTTPS”和“HTTP/2”看成同一个协议。

总结

HTTPS 的核心不是简单地“客户端拿到服务器公钥,再把一个对称密钥发送给服务器”,而是由多个机制共同完成:

  1. X.509 证书和 CA 数字签名验证服务器身份;
  2. ECDHE 等密钥交换机制让双方得到共同秘密,而不直接传输最终会话密钥;
  3. HKDF 等密钥派生机制生成 TLS 会话密钥;
  4. AES-GCM、ChaCha20-Poly1305 等 AEAD 算法保护应用数据的机密性和完整性;
  5. TLS Finished 消息验证握手过程没有被篡改。

HTTPS 主要保护客户端和服务器之间的传输过程,不能替代应用层的身份认证、权限控制、输入校验和端点安全。

参考资料

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS