上一篇讲 TLS 握手,重点在加密。但加密只解决了「别人看不懂」,没解决另一个问题:你怎么确认对面真的是 rubyfun.cn,而不是中间人伪装的?

如果攻击者搭了一个假热点,你在上面连「rubyfun.cn」,攻击者完全可以和自己加密通信——你加密了,但加密的对象是错的。这个问题叫中间人攻击(MITM),TLS 靠证书和信任链来防它。这一篇是连接与传输阶段的收尾,讲清这套身份验证机制。

证书:服务器的身份证

TLS 握手时,服务器会发一个**证书(Certificate)**给客户端。证书就是服务器的「身份证」,核心字段包括:

证书核心字段:域名、有效期、公钥、签发者

  • 域名(CN/SAN):这张证书给哪个域名用。浏览器会严格检查:你访问的是 rubyfun.cn,证书上的域名必须是 rubyfun.cn(或它的通配符 *.rubyfun.cn),不匹配就报错。
  • 公钥:服务器的公钥。TLS 用它做密钥交换,这个公钥和服务器私钥配对。
  • 有效期(Not Before / Not After):证书在哪个时间段有效。过期的证书会被拒绝——这是为什么证书要定期续期。
  • 签发者(Issuer):谁给这张证书签的名。这个字段指向信任链的上一级。

注意一个关键点:任何人都能生成一张「我是 rubyfun.cn」的证书。技术上毫无门槛——用 openssl 几条命令就能生成。那为什么攻击者不自己生成一张假证书来冒充?

因为浏览器不只看证书内容,还要看谁签的名

信任链:根 CA 是信任的锚点

证书要被浏览器信任,必须有**受信任的 CA(证书颁发机构)**签名。而 CA 自己也有层级,形成一条信任链:

信任链:根 CA → 中间 CA → 终端证书

信任链是这样的:

  • 根 CA(Root CA):信任的起点。根 CA 的证书叫「自签名证书」——它自己给自己签。这些根证书预装在操作系统和浏览器里(Windows、macOS、Firefox 各维护一份根证书库)。根 CA 是整个信任体系的锚点,你信任它,是因为它被预装在你设备里了。
  • 中间 CA(Intermediate CA):根 CA 不直接给网站签证书(安全考虑,根 CA 私钥要离线保护),而是签名授权一些中间 CA,让中间 CA 去批量签发。
  • 终端证书(End-entity Certificate):网站实际用的证书,由中间 CA 签发。

验证过程是从终端证书往回追溯:浏览器拿到 rubyfun.cn 的终端证书 → 看它的签发者是某个中间 CA → 找到这个中间 CA 的证书 → 看中间 CA 的签发者是根 CA → 这个根 CA 在我的信任库里吗?在,整条链就通了,证书可信。

这就是为什么攻击者自己生成假证书没用——他没有受信任 CA 的私钥,签的名浏览器不认。这条「从终端到根」的追溯链,是整个 HTTPS 身份验证的基石。

为什么需要中间 CA

根 CA 直接签所有证书不行吗?为什么要多一层中间 CA?两个原因:

  • 安全隔离:根 CA 的私钥是整个体系的命脉,一旦泄露,所有它签的证书都不可信。所以根 CA 私钥保存在离线环境(物理隔离的保险柜里),不轻易动用。日常签发交给中间 CA,万一中间 CA 私钥泄露,只需吊销这个中间 CA,根 CA 和其他分支不受影响。
  • 运营分担:全球上亿网站都要签证书,一个根 CA 忙不过来。中间 CA 可以分散到不同地区、不同业务,提升签发效率。

这也是为什么 TLS 握手时服务器发的不是一张证书,而是一组证书(证书链):终端证书 + 中间 CA 证书。客户端需要中间 CA 证书才能追溯回根 CA。

证书吊销:签发了但失效了怎么办

证书有有效期,但有时候需要提前作废——比如私钥泄露了、域名转手了、公司倒闭了。证书吊销有三种机制:

证书吊销:CRL vs OCSP vs OCSP Stapling

  • CRL(证书吊销列表):CA 定期发布一个「已吊销证书的列表」,客户端定期下载这个列表检查。问题是列表会越来越大,下载耗时,而且更新有延迟——今天吊销的证书,客户端可能明天才下载到新列表。
  • OCSP(在线证书状态协议):客户端实时向 CA 查询某张证书是否被吊销。比 CRL 实时,但问题是要额外一次网络请求(拖慢握手),而且暴露了用户访问了哪个网站(隐私问题,CA 能看到你查它)。
  • OCSP Stapling:让服务器替客户端查好 OCSP 结果,把结果「钉(staple)」在 TLS 握手里发给客户端。这样客户端不用自己查,既快又保护隐私。这是现代推荐的做法。

实战中,很多浏览器对吊销检查的态度很务实:移动端为了速度经常跳过吊销检查(因为 OCSP 查询在弱网下太慢),所以证书吊销在实际中可靠性没那么高。这也是为什么私钥保护很重要——一旦泄露,吊销不一定及时生效。

Let's Encrypt:让 HTTPS 普及的转折

讲证书绕不开 Let's Encrypt。2015 年之前,证书要花钱买,而且申请流程繁琐(要提交企业资料、人工审核),很多小网站嫌麻烦就用明文 HTTP。

Let's Encrypt 改变了这一切:免费 + 自动化。它用 ACME 协议让服务器自动申请、自动续期证书,零成本零人工。结果 HTTPS 普及率从 2015 年的 30% 飙升到现在 80% 以上。这是一个协议设计(ACME)直接改变行业格局的例子。

Let's Encrypt 的证书有效期只有 90 天(传统证书 1 年),这看似短,但配合自动续期反而更安全——证书泄露的暴露窗口更短。这种「短有效期 + 自动化」的理念,后来影响了整个证书行业。

取舍与边界

证书体系有几个值得知道的边界:

  • 信任是预装的:你信任 HTTPS,本质是信任设备里预装的根证书库。这些库由操作系统/浏览器厂商维护,如果它们误装了一个坏 CA(比如曾经发生过),整个信任链就出问题。
  • 证书透明度(CT):为了监督 CA 别乱签证书,引入了 CT 日志——所有签发的证书都要记录在公开日志里,任何人可查。这能发现 CA 的违规签发。
  • 自签名证书不等于不安全:内网服务常用自签名证书(没有 CA 签),技术上加密强度一样,只是浏览器会警告「不可信」。内网可信是因为你控制了分发,不是因为加密弱。

收束:HTTPS 信任的本质是「你信任设备里的根证书库」

TLS 加密保证了机密性和完整性,证书和信任链保证了身份真实性。三者合起来才是完整的 HTTPS 安全。而这套信任的最终锚点,是你设备里预装的根证书库——你信任苹果/微软/Mozilla 预装的这些根 CA,所以才信任它们签出来的所有证书。

连接与传输阶段到这里讲完了。下一篇进缓存——连接建好了、数据传过来了,但同一个资源能不能别每次都传?这就是 HTTP 缓存要解决的。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。

我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。

如果你想继续跟完这套「图解 HTTP」,欢迎关注公众号 「十三Tech」。后续会按 URL 与报文、连接与传输、缓存与协商、安全与边界、HTTP/2 与 HTTP/3 这条线更新。

十三Tech公众号二维码