PKI体系基础:证书、CA、证书链与信任模型

说到TLS,绕不开PKI。很多人觉得PKI就是“证书那一套”,其实没那么简单。

我刚入行时,觉得证书就是个文件,CA就是个发证机构。结果有一次线上服务证书链配错了,用户端报错“证书不受信任”,排查了一整天才发现是中间证书没装全。嗯,从那以后,我再也不敢轻视PKI了。

数字证书:你到底长什么样?

数字证书,说白了就是一张电子身份证。它绑定了公钥和身份信息,由CA签名保证真实性。

最常见的格式是X.509 v3证书。我截个核心字段给你看看:

字段含义我的经验
版本号目前主流是v3v1/v2早过时了,千万别用
序列号CA分配的唯一编号吊销时靠这个找证书
签名算法如SHA256-RSA别用SHA1,不安全
颁发者签发该证书的CA名称常和Subject弄混?看仔细
有效期notBefore ~ notAfter我曾经遇到证书过期1分钟,服务直接断连
主体证书持有者(域名、组织等)多域名用SAN扩展
公钥RSA/ECDSA等密钥长度别小于2048位
扩展密钥用法、基本约束、SAN等CA证书的BasicConstraints必须标记CA:TRUE

小技巧:使用openssl x509 -in cert.pem -text -noout可以直接看证书内容,我排查问题必用这招。

CA:谁给你的证书背书?

CA(证书颁发机构)就是那个给你证书签名的人。它自己也有一个自签名证书,叫根证书。

你想想看:如果谁都能自己签发证书,那浏览器凭什么信任你?所以我们需要一个受信任的第三方。CA就是干这个的。

CA分几类:

  • 公共CA:如DigiCert、Let's Encrypt。浏览器和操作系统默认信任它们。
  • 私有CA:企业内部自己搭的。我所在的公司就自己建了内部CA,管理内网服务证书。
  • 自签名证书:自己签给自己,不经过任何CA。测试环境用用还行,生产环境别这么干。

注意:自签名证书在客户端会报“不受信任”,除非你手动把它的公钥添加到信任库。我在一个项目中被迫用自签名证书做生产,结果每个客户端都要配一遍……别提多痛苦了。

证书链与信任模型:谁信谁?

光有证书和CA还不够。实际中CA是分级的:根CA → 中间CA → 终端证书。

为什么要分层?

  • 根CA私钥一旦泄露,整个信任体系就崩了。所以根CA通常离线保存,用中间CA来签发日常证书。
  • 中间CA可以有不同的策略,比如有的只签服务器证书,有的只签客户端证书。

证书链就是从终端证书一直到根证书的路径。验证时,客户端逐个检查签名,直到找到一个被信任的根证书。

这里面有个关键:信任锚。操作系统或浏览器里预装了一批根证书,那就是信任锚。链上的每个证书都必须由上一级签发,并且不能过期、不能吊销。

核心原则:
1. 终端证书 + 所有中间证书 = 完整的证书链。
2. Nginx/Apache配置证书时,必须把中间证书也拼接进去。
3. 我见过有人只配了服务器证书,客户端死活连不上——就是中间证书没带。

为了让你更直观地理解,我画了张PKI信任模型的结构图:

PKI信任模型结构图 根CA(离线) 中间CA (签发服务器) 中间CA (签发客户端) 服务器证书 客户端证书 代码签名证书 信任锚:浏览器/操作系统预装的根证书 → 沿箭头方向验证 → 最终信任终端证书

信任模型:不同场景怎么选?

常见的信任模型有这些:

模型描述适用场景
层级模型根CA → 中间CA → 终端证书,严格树状公共PKI、企业内网
网状模型多个CA互相交叉认证大型企业联盟
桥CA模型用一个桥CA连接不同PKI域跨公司信任

我个人习惯用层级模型。原因很简单:好管理,易排查。根CA锁在离线机器里,中间CA在线签发,出了问题最多吊销中间CA,根CA不受影响。

避坑指南:我曾经给内部CA配证书链时,忘了给中间CA添加basicConstraints=CA:TRUE。结果中间CA签发的证书客户端验证不通过。各位千万别漏了这个扩展。

证书的吊销机制

证书被泄露了怎么办?必须吊销它。

两种常见方式:

  • CRL(证书吊销列表):CA定期公布黑名单。缺点是列表可能很大,而且有延迟。
  • OCSP(在线证书状态协议):实时查询单个证书状态。更快但需要CA在线服务。

我在生产环境遇到过CRL过期导致TLS握手失败的情况。后来改成OCSP Stapling,让服务端自己缓存OCSP响应,客户端不用额外请求,性能好很多。

总结一下

PKI的核心就是三样东西:证书(证明身份)、CA(背书的人)、证书链(信任的路径)。

你只要记住:
- 证书链要完整,缺一个中间证书都不行。
- 根CA要保护得像命根子一样。
- 吊销机制不能省,万一私钥泄露,没吊销等于给别人开后门。