3、证书管理:X.509证书结构、证书链验证、CA与中间CA
说起证书管理,很多人第一反应就是“拿到一个证书文件,配置到服务器上就完事了”。
但说实话,做TLS审计的时候,这才是最容易出坑的地方。我见过太多团队只盯着密码套件,结果证书链根本没配全,中间CA一丢,客户端死活连不上。曾经有个客户折腾了三天,最后发现是少发了一张中间CA证书。
所以这一章,咱们把证书的里里外外彻底说清楚。
3.1 X.509证书结构——拆开看看里面到底有什么
X.509是PKI体系里最核心的标准,目前主流是v3版本。你平时看到的.crt、.pem、.cer文件,底层都是X.509结构。
说白了,它就是一张有标准格式的“数字身份证”。
核心字段清单
| 字段 | 说明 | 审计关注点 |
|---|---|---|
| 版本号 (Version) | 0=v1, 1=v2, 2=v3,现在几乎全用v3 | 忽略v3扩展能力的证书可能不完整 |
| 序列号 (Serial Number) | CA签发的唯一整数,不得重复 | 弱随机序列号可被预测,曾爆过漏洞 |
| 签名算法 (Signature Algorithm) | 签发时使用的哈希+非对称算法,如sha256WithRSAEncryption | 必须≥SHA-256,SHA-1已全面废弃 |
| 颁发者 (Issuer) | 签发该证书的CA的DN(Distinguished Name) | 证书链验证时逐级匹配的关键 |
| 有效期 (Validity) | notBefore和notAfter | 是否已过期、是否在签发时使用了未来时间 |
| 主体 (Subject) | 证书持有者的DN | 是否与当前域名或组织一致 |
| 公钥 (Subject Public Key Info) | 算法+公钥值,如RSA 2048位或EC P-256 | 密钥长度是否达标,RSA<2048直接否决 |
| 扩展 (Extensions) v3新增 | 包含基本约束、密钥用法、SAN等关键属性 | 审计核心区域,后面详细说 |
v3扩展:审计的“照妖镜”
我个人最看重的就是扩展区。很多伪造证书或者配置错误的证书,在扩展区一眼就能看出问题。
- Basic Constraints:标记该证书是否为CA。如果普通终端证书误加了
CA:TRUE,那它就能签发其他证书,想想就可怕。 - Key Usage:指定公钥用途,比如
digitalSignature、keyCertSign。keyCertSign只能CA证书有,终端证书有就是违规。 - Subject Alternative Name (SAN):现代浏览器基本只看SAN,不看CN。很多旧证书只配了CN,没配SAN,直接导致浏览器报不安全。
- Extended Key Usage (EKU):限制证书用途,比如
serverAuth、clientAuth。我曾经审计过一个客户,服务器证书上只配了emailProtection……连https都走不了。
openssl x509 -text -noout先扫一遍扩展区,优先级最高。Basic Constraints、Key Usage、EKU这三个字段但凡有一个不对劲,直接标红。
3.2 证书链验证——信任是怎么一步一步传递的
你想想看,互联网上成千上万的服务器,客户端凭什么相信你出示的那张证书?
答案就是证书链(Certificate Chain)。信任不是凭空产生的,而是从根CA开始,一级一级签下来的。
证书链的三层模型
- 根CA(Root CA):自签名证书,信任锚点。预埋在操作系统或浏览器里。
- 中间CA(Intermediate CA):由根CA签发,用于分担风险和业务隔离。
- 终端证书(Leaf/End Entity):最终给网站或设备用的,由中间CA签发。
验证过程长这样(我用通俗的话讲)
客户端收到服务器证书后,会做这么几件事——
- 先检查终端证书本身的签名:用签发者的公钥去解签名,算哈希,比对。这一步用的是“颁发者”字段指向的证书的公钥。
- 接着往上找签发者证书。如果服务器没发中间CA,客户端就得自己去本地信任库里找。找不到?验证失败。
- 重复这个步骤,直到遇到一个自签名的根证书,并且这个根证书正好在客户端的信任列表里。
- 每跳一级都得检查:签名对不对、有效期、证书是否被吊销、Basic Constraints是否允许做CA。
审计中最常见的翻车现场
检查命令也很简单:
openssl s_client -connect yoursite.com:443 -showcerts,看返回的证书数量是不是≥2(终端+中间)。
3.3 CA与中间CA——为什么说中间CA是双刃剑
根CA是整个PKI体系的命根子。一旦根CA私钥泄露,所有由它签发的证书都要作废。所以现代PKI都很聪明——根CA只做一件事:签发少量的中间CA,然后自己“离线锁死”。
日常签发证书的工作全部交给中间CA处理。
为什么企业要用自己的中间CA?
| 对比维度 | 直接用公共CA签发 | 自建中间CA+公共根CA |
|---|---|---|
| 控制力 | 完全依赖第三方CA | 自己控制签发策略,吊销也快 |
| 安全隔离 | 根CA一旦被攻破,全军覆没 | 中间CA泄露可吊销重建,根CA安全 |
| 证书数量 | 每张证书都得花钱 | 内部证书随便签,零成本 |
| 兼容性 | 所有设备都信任 | 需要把中间CA分发到所有受控设备 |
审计中间CA时我必查的三个点
- 中间CA的Key Usage和Basic Constraints:必须包含
keyCertSign和CA:TRUE。我见过有人把中间CA配成了终端证书,结果所有下级证书验证全挂。 - 路径长度约束(Path Length Constraint):根CA签发中间CA时,可以限制它最多还能签发多少级CA。比如
pathLenConstraint:0表示它只能发终端证书,不能再发下级CA。这个字段能防止CA无限扩张。 - 中间CA的有效期:通常比终端证书长,但不能超过根CA。曾经有客户用了一张已经过期的中间CA去签发新证书……嗯,全公司不能用。
到这里,证书的骨架你应该已经搭起来了。下面我用一张图把整个信任链的逻辑串起来——
我从实际项目中做证书审计的路径,基本也是这张图的逆序——先看终端证书的SAN和Key Usage,再向上追中间CA的有效期和Basic Constraints,最后确认根CA是否在信任库内。
好了,证书的结构、信任链的验证逻辑、CA和中间CA的分工,我们已经理清楚了。这些都是做TLS审计的底子,后面讲到证书吊销、ocsp stapling的时候,还会反复用到这些概念。