关于本文
本文查阅了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)即可”的理解,对于当前的服务身份验证来说已经不再适用了。
如果名称不匹配,即使出示了其他合法的证书,也不能判定为“试图访问的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

