HTTPS的证书究竟在验证什么?——通过序列图看TLS连接的入口

ネットワーク・RFCカテゴリを表すパンダのイラスト 网络・RFC

关于本文
本文查阅了TLS 1.3与服务名验证的现行RFC,梳理了服务器证书在HTTPS中发挥的作用。

验证状态:📘 已确认官方规范・公开网站观察未固定
由于TLS实现和浏览器显示因环境而异,本文将以协议上的角色为中心进行说明,而不是针对特定产品的界面。

HTTPS的服务器证书并不是“单纯用来加密通信的文件”。它是在TLS连接中,将连接目标名称与公钥绑定,并利用连接到受信任证书颁发机构的证书链,作为验证对方服务器identity的材料。

TLS将这种验证与密钥协商结合起来,建立通信所需的session key。

宏观查看TLS 1.3的流程

sequenceDiagram
    participant C as Client
    participant S as HTTPS Server

    C->>S: ClientHello
    S-->>C: ServerHello
    S-->>C: Certificate
    S-->>C: CertificateVerify
    S-->>C: Finished
    C->>C: 証明書・名前・署名等を検証
    C-->>S: Finished
    Note over C,S: 暗号化されたapplication data

实际的TLS 1.3 handshake根据条件会有所不同,但只要掌握了“接收证书 → 验证identity和证书链 → 确认server持有私钥 → 完成handshake”这一逻辑关系,就很容易理解整体流程了。

证书究竟验证了什么

典型的验证视角如下。

  • 试图连接的service名称是否与证书的identifier相匹配

  • 证书的有效期等是否合理

  • 是否能够构建并验证通往受信任证书颁发机构的certificate path

  • 在TLS handshake中,server能否证明其持有与证书公钥相对应的私钥

flowchart TB
    A[Server certificate] --> B[名前の一致]
    A --> C[有効性]
    A --> D[Certificate chain]
    D --> E[Trust storeの信頼 anchor]
    A --> F[CertificateVerify]
    F --> G[対応する秘密鍵を持つことの証明]

URL的主机名与什么进行比较

根据现行的IETF RFC 9525,服务身份(service identity)的DNS名应与subjectAltName中的dNSName等适当的identifier进行匹配。

过去常见的“只需查看通用名(Common Name)即可”的理解,对于当前的服务身份验证来说已经不再适用了。

Example Domain
↓ reference identifier: www.example.com ↓ 与证书的subjectAltName等进行比对

如果名称不匹配,即使出示了其他合法的证书,也不能判定为“试图访问的service的证书”。

什么是证书链

我们不能单凭server certificate本身来信任它,而是需要追溯其issuer(签发者),一直验证到客户端trust store中的trust anchor(信任锚)。

flowchart TB
    A[Server / Leaf certificate] --> B[Intermediate CA]
    B --> C[Root CA]
    C --> D[Client trust store]

实际的path building(路径构建)和validation(验证)要复杂得多,但对于初学者建立的第一印象来说,这种关系最容易理解。

只要有了证书,通信内容就会全部用该公钥加密吗?

在TLS 1.3中,并不是简单地利用certificate的公钥直接加密整个网页的正文。

我们在handshake中进行密钥协商,并使用由此获得的秘密来保护application data。证书对于server authentication(服务器身份验证)非常重要,但最好不要将其与session data的加密方式等同视之。

在使用curl遇到证书错误时

curl会执行TLS certificate verification。如果名称不匹配、无法构建信任链等,就会产生verify error。

在日常使用中,应避免将 -k / –insecure 作为“消除错误的方法”频繁使用。

flowchart TB
    A[curl HTTPS] --> B{certificate verification}
    B -->|OK| C[HTTPS requestを継続]
    B -->|NG| D[verify error]
    D --> E[名前・期限・chain・CA設定を調査]
    E -. 安易に検証無効化しない .-> D

验证错误并不是烦人的功能,而是一个用于通知用户无法确认连接目标identity的安全机制。

DNS正确,证书就一定正确吗?

通过DNS解析到正确的IP地址,与通过TLS验证连接目标的identity,属于不同的层级。

flowchart LR
    A[DNS] --> B[接続先IPを得る]
    B --> C[TCP接続]
    C --> D[TLS handshake]
    D --> E[certificateでservice identityを検証]
    E --> F[HTTP]

将这些层级分开来看,就不容易把DNS故障、TCP连通性问题、TLS certificate error以及HTTP error混为一谈了。

总结

  • 服务器证书将连接目标identity与公钥联系在一起

  • client会检查名称、certificate path以及有效性等

  • 在TLS 1.3中,还会通过CertificateVerify等方式确认server是否持有私钥

  • 并不是用证书的公钥直接把整个Web正文全部加密

  • 应将DNS、TCP、TLS和HTTP视为独立的层级进行划分

  • 切勿轻易禁用certificate verification

官方信息与一手资料

RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3
https://www.rfc-editor.org/rfc/rfc8446.html

RFC 9525 — Service Identity in TLS
https://www.rfc-editor.org/rfc/rfc9525.html

curl — TLS certificate verification
https://curl.se/docs/sslcerts.html

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
标题和URL已复制