4. 数字证书与PKI体系:X.509证书格式、CA链、证书吊销

讲到TLS握手,绕不开数字证书。你可能觉得证书就是个文件,配好就行。但真到排障时,很多问题都出在证书身上。我见过不少团队因为证书链不全,导致生产环境大面积中断。今天咱们就把这背后的PKI体系彻底捋清楚。

4.1 X.509证书格式——证书的“身份证”

X.509是国际标准,定义了数字证书的格式。目前用最多的是v3版本。它不像普通文件那样随便写几行字段,而是用ASN.1编码的。

我早期做安全开发时,第一次用openssl x509 -text命令看证书,被一大堆字段吓到了。其实核心就那么几个:

字段含义备注
Version版本号(v1/v2/v3)现在基本都用v3
Serial Number证书序列号(唯一)CA分配,吊销时用
Signature Algorithm签名算法比如SHA256withRSA
Issuer颁发者(CA名称)谁签的
Validity有效期(起止时间)别过期了
Subject主体(证书持有者)就是你的域名/组织
Subject Public Key Info公钥算法+公钥值TLS握手时用
Extensions扩展项(v3才有)关键扩展:CA标志、密钥用法等

重点:Signature字段是CA用自己私钥对证书内容签名的结果。客户端验证证书时,会用CA公钥算一次,确认没被篡改。

咱们用命令看一下真实证书结构:

openssl x509 -in example.crt -text -noout

输出里有一个类似这样的片段:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 0x12345678...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, O=Example CA, CN=Example Root CA
        Validity
            Not Before: Jan  1 00:00:00 2024 GMT
            Not After : Jan  1 00:00:00 2025 GMT
        Subject: C=CN, O=Example Org, CN=www.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            ...

嗯,这里要注意:Basic Constraints 这个扩展非常重要。CA证书的CA标志为TRUE,终端用户证书为FALSE。如果乱配,客户端会认为它是非法CA,直接拒绝连接。我见过有人把终端证书的CA标志误设成TRUE,结果浏览器报错“证书链不完整”。

4.2 CA链——信任的传递

单独的证书没有意义,必须有一条完整的证书链。根CA自签名,然后签发中间CA,中间CA再签发终端证书。客户端验证时,要用信任库里的根证书去校验上一级签名,一级级往上推。

为什么要有中间CA?直接根CA签发终端证书不更简单吗?

说实话,这么做是为了隔离风险。根CA私钥如果泄露,整个体系就完了。所以一般把根CA离线冷存储,日常签发用中间CA。就算中间CA出事,吊销它就行,根CA还能继续用。我在给金融客户做PKI方案时,他们要求根CA的私钥必须放在硬件加密机里,物理隔离。

典型的CA链结构:

  • 根CA证书(自签名,信任锚)
  • 中间CA证书(由根CA签发,CA标志为TRUE)
  • 终端证书(由中间CA签发,CA标志为FALSE)

服务器配置时,需要把中间CA和终端证书拼接在一起发过去,根证书不用发(客户端自己已预置)。很多新手把根证书也塞进去,或者顺序放反,导致验证失败。

小技巧:用 openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt 可以快速验证链是否完整。我每次发布前都会跑一次这个命令,避免人工拼错。

4.3 证书吊销——CRL与OCSP

证书不是永久的。私钥泄露、域名变更、员工离职……都需要吊销证书,让客户端不再信任它。两种主流方式:CRL(证书吊销列表)和OCSP(在线证书状态协议)。

方式原理优点缺点
CRLCA定期发布一个列表,包含所有被吊销证书的序列号实现简单,离线可查列表会变大,有延迟
OCSP客户端实时向OCSP响应器查询单个证书状态实时性强,负载小依赖网络,OCSP响应器可能宕机

实际部署中,OCSP更常用。但有个坑:OCSP必须响应快,否则客户端会超时。我经历过一次OCSP响应器性能不足,导致TLS握手变慢,用户抱怨页面加载卡顿。后来加了OCSP Stapling,让服务器自己缓存并推送状态,问题才解决。

注意:CRL和OCSP都不是实时的,有吊销延迟。所谓“实时吊销”其实靠缩短CRL有效期或OCSP缓存时间来实现。理论上私钥泄露后,攻击者仍可能用已吊销的证书短暂攻击。这一点在合规审计时要考虑。

查看CRL的方法:

openssl crl -in crl.pem -text -noout

OCSP请求示例(用openssl模拟):

openssl ocsp -issuer intermediate.crt -cert server.crt -url http://ocsp.example.com -text

4.4 知识结构图

下面这张图把PKI体系的核心概念串起来了。

PKI体系知识结构 PKI 体系 X.509 证书格式 CA 信任链 证书吊销 主体/颁发者 公钥/签名 扩展项(v3) 根CA 中间CA 终端证书 CRL OCSP 三层结构:根CA离线 → 中间CA签发 → 终端证书对外服务 吊销方式:CRL批量更新 | OCSP实时在线查询

核心回顾:证书格式是基础,CA链构建信任,吊销机制确保撤销能力。三者缺一不可。配置TLS时,记住这三步:检查证书格式是否完整(含扩展项)→ 确认链顺序是否正确 → 确保OCSP/CRL可达。曾经有个客户线上证书过期,就是因为CRL缓存没有及时刷新,导致客户端一直走旧查询路径。从那以后我养成了一个习惯:每次证书轮换,都把新的CRL分发点也验证一遍。

本章内容到此结束。理解这些,你就能在TLS证书相关的问题上游刃有余了。