第2章:证书结构——公钥、私钥、CA链

说到TLS证书,很多人第一反应就是“那个加密文件”。其实不然。证书本身是个结构化的数据容器。我习惯把它想象成一个透明的档案袋,里面装着几样关键东西——公钥、身份信息、有效期,还有签发者的签名。

要搞懂轮换,你得先摸清楚这个档案袋里到底有什么。咱们一个一个拆开看。

2.1 公钥与私钥——天生的搭档

公钥和私钥,说白了就是一把锁和一把钥匙。私钥你藏好,公钥你可以满大街贴。

  • 私钥:必须保密。谁拿到它,谁就能冒充你。我在项目中见过有人把私钥放在代码仓库里——嗯,那次事故挺严重的。
  • 公钥:装在证书里发给对方。对方用公钥加密数据,只有你能用私钥解密。

我们来看一个典型的RSA密钥对生成命令:

# 生成私钥(2048位,推荐)
openssl genrsa -out server.key 2048

# 从私钥提取公钥
openssl rsa -in server.key -pubout -out server.pub

你在轮换时,最常碰到的就是私钥更新。公钥跟着证书一起发出去就行。但我提醒你一句:私钥生成时一定要设好权限。chmod 600,别偷懒。

我个人的习惯:每次生成新私钥后,先跑一遍 openssl rsa -check -in server.key,确认私钥文件没损坏。浪费三秒钟,省掉三小时排查时间。

2.2 X.509证书结构——标准的骨架

目前TLS证书使用X.509 v3标准。这块结构非常固定,你打开一个证书就能看到这些字段:

字段 说明 轮换时要注意的
版本号 目前是V3 不用管它
序列号 CA分配的唯⼀编号 每次轮换都会变
签名算法 如SHA256-RSA 避免使用SHA1,已不安全
颁发者 签发此证书的CA名称 确认和CA链匹配
有效期 notBefore和notAfter 轮换前留足够缓冲期
主体 证书持有者名称(CN) 必须匹配你的域名
公钥 算法+密钥内容 和私钥配成一对
扩展项 SAN、密钥用法、CRL地址等 SAN是最容易漏配的
CA签名 CA用私钥签名的指纹 验证证书是否被篡改

你可以用这条命令查看证书的完整结构:

openssl x509 -in certificate.crt -text -noout

输出内容很长。我重点让你看三个地方:Subject、Issuer、和X509v3 Subject Alternative Name。轮换时,这三个地方但凡有一个和旧证书对不上,客户端就可能报错。

2.3 CA链——信任链条的搭建

CA链,你可能听过“证书链”或“信任链”。它解决一个核心问题:凭什么相信你的证书是真的?

你的证书由中间CA签发,中间CA由根CA签发。根CA的证书预装在操作系统或浏览器里。这样就形成了一条信任路径。

轮换时容易踩的坑:很多人只换了服务器证书,却忘了附带中间CA证书。客户端验证时找不到完整的链,直接报“不信任”。

标准做法是把服务器证书和中间CA证书拼接成一个文件:

cat server.crt intermediate.crt > fullchain.crt

然后配置Web服务器指向这个fullchain.crt。我自己习惯按这个顺序:服务器证书法 → 中间CA → 根CA。虽然根CA一般不要求上传,但加上没坏处。

我遇到过的线上事故:有一次nginx配置里只配了server.crt,没配中间CA。看起来一切正常,但安卓客户端全部连接失败。因为安卓不缓存中间CA。从那以后,我的轮换清单里多了一条——检查fullchain里到底有几张证书。

验证方法:
openssl crl2pkcs7 -nocrl -certfile fullchain.crt | openssl pkcs7 -print_certs -text | grep "Subject:"

2.4 核心流程一图看明白

我把公钥、私钥、CA链之间的关系画成一张图。你看了应该能秒懂:

TLS证书结构核心逻辑 私钥 server.key 登录放好,只读600 公钥 server.pub 会存入证书中 openssl rsa -pubout X.509证书 server.crt 内含:公钥 + 身份 + CA签名 嵌入 CA信任链 根CA → 中间CA → 服务器证书 全链拼接成 fullchain.crt 链式验证 验证过程: 客户端收到证书 → 提取CA签名 → 验证签名是否由上级CA签发 → 逐级上溯到根CA → 根CA在信任库中 → 信任建立

2.5 轮换操作中的常见误区

结合刚才讲的证书结构,我列出几个经常踩坑的点。你轮换时挨个检查,能省不少事:

  1. 私钥和证书不配对:新生成私钥后,签出来的证书必须用这把私钥。我习惯轮换时直接重新生成一对,避免混淆。
  2. CA链不完整:尤其你用了私有CA或中间CA时,客户端经常抱怨“无法验证证书”。放全链就行。
  3. SAN(主题备用名称)丢失:旧证书可能有 multiple domain 的支持。新证书里如果有漏配的,用户访问那个域名就会弹安全警告。
  4. 序列号重复:这个其实CA会帮你管,但如果你自签证书,记得序列号别和上一轮一样。
我曾经漏配SAN吃过亏:给一个多域名的Nginx换证书后,api.example.com正常,www.fallback.com挂了。排查半天才发现新证书SAN里没写fallback域名。从那以后,每次换证书前我都拿旧证书和新证书对比一下SAN字段:
diff <(openssl x509 -in old.crt -text -noout | grep DNS:) <(openssl x509 -in new.crt -text -noout | grep DNS:)

2.6 小结

证书结构这块,你记住三样东西就行:私钥保管好,公钥放进证书,CA链要拼全。轮换的时候,这三样缺一不可。

下回你换证书,打开证书文件看一眼——Subject、Issuer、SAN、公钥、CA签名,这些字段都正常,基本就稳了。