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用私钥对上述内容的数字签名
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,链完整,证书可信。
自签名证书——什么时候用?
自签名证书就是自己给自己签发,Issuer = Subject。它没有上层CA背书。开发环境、内网测试、小型实验场景都能用。
但是,你真要用在双向认证的生产环境?我个人不建议。理由有三:
- 无法吊销:出问题没法通知各方废掉这个证书
- 没有信任分层:所有客户端必须手动导入你的自签名根证书
- 审计困难:出事了查不到是谁签发的
不过话说回来,调试时自签名很香。生成命令:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
这行命令我几乎每周都要用一两次。
捋一遍完整结构——看SVG图
下面这张图把整个证书体系串起来了,你仔细过一遍:
看上图你就明白了:整个体系是树形结构。信任起点永远是根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双向认证就能走得更顺。