X.509证书体系:CA、证书链、自签名证书

讲到TLS双向认证,绕不开证书。X.509就是那个定义证书格式的标准。说实话,我早些年刚接触时也犯过糊涂——根证书、中间证书、服务器证书,到底谁签谁?

那咱们今天就把它掰扯清楚。

X.509证书长什么样?

X.509证书说白了就是一个数据结构。里面塞了公钥、身份信息、有效期、签名等字段。我用OpenSSL随便生成一个看看内容:

openssl x509 -in cert.pem -text -noout

输出结果你会看到:

  • Subject:证书持有者,比如 CN=example.com
  • Issuer:签发者,谁给这个证书签的名
  • Validity:起止时间
  • Public Key:公钥算法和密钥内容
  • Signature:CA用私钥对上述内容的数字签名
小经验:我常跟团队说,看证书先看Issuer和Subject是否一样。一样就是自签名,不一样就是CA签发。这招能快速定位问题。

CA、根CA、中间CA——到底谁是谁?

CA全称Certificate Authority,证书颁发机构。它的工作就是:验证申请者身份 -> 用自己私钥给对方的公钥签名 -> 生成证书。

但一个CA不可能只签一层。安全实践里通常分层:

层级 角色 特点
根CA 信任锚点 自签名,离线保存,很少直接签发终端证书
中间CA 受根CA签发 可在线,签发下级或终端证书
终端证书 最终用户/服务器 由中间CA签发,用于实际通信

为什么搞这么复杂?我个人习惯把它比喻成"护照签发体系"。公安部(根CA)授权各省厅(中间CA),省厅再给你办护照(终端证书)。哪个环节出问题都能吊销,而不需要废掉整个体系。

证书链——验证信任的路径

双向认证时,客户端收到服务端证书,怎么知道它可信?顺着链条往上找父证书,直到找到你信任的根CA。这个过程叫证书链验证。

举个例子,你拿到一个证书A,它的Issuer是B。你去找证书B,B的Issuer是C。C是根CA(自签名),并且C已经在你的信任列表里。OK,链完整,证书可信。

我曾经踩过的坑:在网关项目中,我把根证书的私钥直接放在业务服务器上,想着方便。结果某次运维误操作把根私钥暴露到了Git仓库……后来重建了整个PKI体系。血的教训:根CA的私钥必须离线保管,最好物理隔离。

自签名证书——什么时候用?

自签名证书就是自己给自己签发,Issuer = Subject。它没有上层CA背书。开发环境、内网测试、小型实验场景都能用。

但是,你真要用在双向认证的生产环境?我个人不建议。理由有三:

  • 无法吊销:出问题没法通知各方废掉这个证书
  • 没有信任分层:所有客户端必须手动导入你的自签名根证书
  • 审计困难:出事了查不到是谁签发的

不过话说回来,调试时自签名很香。生成命令:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

这行命令我几乎每周都要用一两次。

捋一遍完整结构——看SVG图

下面这张图把整个证书体系串起来了,你仔细过一遍:

X.509证书体系结构图 X.509 证书体系结构 根CA 自签名,离线保管 中间CA-1 由根CA签发 中间CA-2 由根CA签发 终端证书A 服务器A 终端证书B 服务器B 终端证书C 客户端C 终端证书D 客户端D 证书链验证路径 终端证书 → 中间CA → 根CA → 信任存储区 客户端信任存储

看上图你就明白了:整个体系是树形结构。信任起点永远是根CA。双向认证时,客户端和服务端互相出示证书,然后逐级往上验证,最后落到对方的根证书上。

重点记忆:在双向认证里,服务端也要验证客户端证书。所以服务端得存一份包含根CA和中间CA的信任列表。客户端同理。缺了任何一个中间节点,链就断了,认证就会失败。

实操中怎么配证书链?

假设你从某CA购买了证书,他们会给你三个文件:你的终端证书、中间CA证书、根CA证书。部署时不能只丢终端证书出去,你得把中间CA和根CA一起打包发给对端。

我一般这样拼接:

cat end_cert.pem int_ca.pem root_ca.pem > fullchain.pem

这种"证书链文件"在nginx、Tomcat里直接引用即可。OpenSSL验证链时也是从上到下逐个检查签名。

注意:千万别把私钥也拼进去。有人图省事把私钥和证书放一个文件,结果分发出去后私钥泄露。私钥就只能藏在服务器本地。

自签名证书的坑与正确用法

我自己做实验时经常自签名。但你们要记住,自签名证书无法吊销。一旦私钥泄露,你只能重新生成证书,然后通知所有客户端更新。

正确做法:自己建一个迷你CA体系。根CA自签名,再签一个中间CA,用中间CA去签终端证书。这样将来吊销只需要吊销终端证书,根和中间不受影响。如果是生产环境,我强烈建议走这个流程。

当然,小团队开发阶段自签名够用了。我上一个项目就全程用自签名证书联调,上线前才换成正规CA签发的证书。

总结一下知识要点

  • X.509证书就是公钥+身份+签名
  • 证书链:从终端往上找到根,根必须在信任存储
  • 根CA私钥必须离线,中间CA可以在线
  • 自签名只适合测试,生产用三级CA体系
  • 双向认证时双方都要验证对方的证书链

证书体系说复杂也复杂,说简单其实就那么几样东西。掌握了结构,后面配置tls双向认证就能走得更顺。