2.1 X.509 与 PKI:证书链、服务身份与撤销
一段公钥字节既不能证明对端持有私钥,也不能证明对端就是 api.example.com。握手签名等协议步骤证明私钥持有,证书与本地信任策略负责身份绑定。PKI 的任务是把公钥、命名身份、用途、有效期和签发策略连接起来,并让客户端按本地信任锚验证整条路径。
证书是一份被签名的声明
一张 X.509 叶子证书通常包含:
Subject public key
Serial number
Validity: notBefore / notAfter
Subject Alternative Name (SAN)
Key Usage / Extended Key Usage
Issuer
CA signature algorithm + signature
其他约束扩展证书不包含私钥。若把私钥 .key 打进公开镜像,拿到它的人就可能冒充证书主体;证书 .crt 本身通常可以公开。
遵循 RFC 9525 的 TLS 客户端从 subjectAltName 匹配服务身份,不退回检查 Subject Common Name;它已取代 RFC 6125。DNS 名使用 dNSName,IP 字面地址则匹配 SAN 中的 iPAddress,不能靠反向 DNS 猜测身份。通配符只能作为完整的最左标签,例如 *.example.com,它既不匹配 example.com,也不匹配 a.b.example.com;若共享这份通配符证书的私钥泄露,受影响的主机范围也会扩大。
链不是简单的字符串列表
本地 trust anchor(根 CA)
↓ 签发
Intermediate CA
↓ 签发
Leaf certificate: api.example.com客户端通常在本地保存根信任锚,服务端发送叶子和必要的 intermediate。根证书一般无需由服务端发送;漏发 intermediate 会导致部分客户端无法构建路径。
路径验证至少涉及:
- 每级签名是否有效,能否连接到本地信任锚;
- 当前时间是否在验证路径中各证书的有效期内,信任锚另按本地策略处理;
basicConstraints是否允许该证书作为 CA;- path length、name constraints 和 policy constraints 是否满足;
- key usage / extended key usage 是否允许当前用途;
- 叶子 SAN 是否匹配客户端独立构造的 reference identity;
- 本地策略是否要求撤销状态、算法强度或其他约束。
“证书签名正确”只是其中一步。客户端必须从自己打算访问的 URL/服务配置构造期望身份,不能拿证书自己声明的名字反过来当期望值。
用路径正确但名字错误的证书试一次
准备由受控测试 CA 签发的 leaf.pem、中间证书 intermediates.pem,以及独立选定的信任锚 roots.pem。叶证书应包含 DNS:api.example.com SAN 与服务器认证用途。下面只读取本地文件,不向系统信任库导入证书。
openssl verify -CAfile roots.pem -untrusted intermediates.pem \
-purpose sslserver -verify_hostname api.example.com leaf.pem正确配置应返回 leaf.pem: OK。再把目标名改为 other.example.com、去掉必需的中间证书,或换成不受信的根,分别应失败。-verify_hostname 不会自动要求所有应用遵循同一身份政策,实际客户端仍需按 RFC 9525 配置;此命令也未执行在线撤销查询或浏览器 CT 政策。参数含义见 OpenSSL 验证选项。
Trust store 决定信任边界
证书链最终落到哪个 trust anchor,是客户端的策略。公网 Web PKI、企业私有 CA、设备制造 CA 和服务网格 CA 不应无边界混用。
若设备未再限制用途或命名空间,把企业根 CA 加入其信任库便授予了广泛的签发信任。私有 PKI 要限制 intermediate 的名称和用途、保护离线 root、缩短在线签发层级权限,并建立证书清单和撤销能力。
自签名证书不是天然“不安全”,问题在于信任如何分发和更新。开发环境可以显式安装受控本地 CA;生产客户端不应通过“忽略所有证书错误”来支持自签名。
撤销机制有可用性权衡
证书到期是可预测失效,私钥泄露则需要提前撤销。常见机制:
- CRL:定期下载撤销序列号列表,简单但可能较大且不够实时;
- OCSP:在线查询单张证书状态,增加隐私与可用性依赖;
- OCSP stapling:服务端携带签发 CA 或获授权 OCSP 响应者签名的状态响应,减少客户端查询;
- 短生命周期证书:缩短泄露窗口,但要求自动签发高度可靠。
不同客户端对软失败、硬失败和 stapling 的处理不同,不能把“CA 已提供 OCSP”写成端到端撤销一定生效。Must-Staple 只对实现并执行该扩展的客户端产生预期约束;采用前应评估响应更新失败会不会造成大面积中断。短生命周期也只限制证书被接受的时间,不等于泄露后立即撤销。
Certificate Transparency 负责可发现性
CT 使用公开、可审计的 append-only log 记录公网证书或 precertificate。域名所有者可以监控未授权签发,浏览器也能按自身策略要求合格日志的 SCT。SCT 是日志承诺在期限内收录的签名声明,并不是证书已完成日志收录的证明;实际收录还要检查包含证明。
CT 不会阻止 CA 误签,也不会替客户端完成 hostname 与路径验证。它让误签更容易被发现和追责,因此还需要告警、撤销和应急换证流程。
Pinning 容易把安全问题变成可用性事故
把客户端固定到单张叶子证书,在证书正常轮换、CA 切换或紧急重签时会让客户端全部断连。若确有高风险封闭场景,应固定经过设计的公钥集合或信任锚,准备重叠 key、备份 pin 和带签名的更新路径。
浏览器应用通常依赖平台 Web PKI 与 CT,而不是自行实现 HPKP 一类 pinning。服务身份校验失败应默认终止,不能弹一个“继续访问”就把责任交给不理解证书链的用户。
运维检查
- SAN 是否恰好覆盖需要的身份,而非过宽通配符?
- 服务是否发送完整 intermediate chain?
- 私钥是否可导出,谁能读取,是否记录使用审计?
- 证书、intermediate 和 trust anchor 的到期是否分别监控?
- 算法、key usage、EKU 与证书用途是否一致?
- 私钥泄露后,撤销、重签、发布和验证要多久?
- 客户端时钟错误与 CA/OCSP 不可用时如何表现?
下一课把证书放进 TLS 1.3 握手与自动轮换。