x509 证书结构:证书格式、字段含义、扩展项

咱们做 mTLS,天天跟证书打交道。x509 证书长什么样?里面都有啥?说实话,我刚开始接触时也一头雾水。后来在生产环境踩过坑,才真正把每个字段研究明白。

证书不是一堆乱码。它有严格的结构。你把它用 ASN.1 描述,再用 DER 编码,最后用 PEM 展示。嗯,咱们从最直观的格式开始讲。

证书格式:DER 与 PEM

证书有两种常见形态:二进制 DER 和文本 PEM。

  • DER – 原始二进制,.cer 或 .der。给机器用的,人眼看不懂。
  • PEM – 用 Base64 编码 DER,外带头尾标记。比如 -----BEGIN CERTIFICATE-----。文本友好,方便复制粘贴。

我在项目中遇到过有人直接把 PEM 贴到代码里当字符串用,结果换行符被吞掉,解析失败。这种低级错误排查起来最费时间。所以现在我习惯用 Base64 压缩成一行,或者用环境变量传入。

小技巧:用 OpenSSL 查看证书内容,命令:openssl x509 -in cert.pem -text -noout。这样能看到全部字段,比对着二进制瞎猜强多了。

证书字段含义

一张 x509 v3 证书,核心字段就这么几个。我整理了一个表格,你对照着看。

字段 含义 避坑点
Version 版本号(v1/v2/v3)。现在全用 v3,支持扩展项 v1 证书不能有扩展,检查旧系统时注意
Serial Number 颁发者分配的唯一标识 序列号重复会导致吊销列表混乱
Signature Algorithm 签名算法,如 SHA256-RSA 别用 SHA1,已被攻破
Issuer 颁发者 DN(Distinguished Name) 如果 DN 不一致,证书链验证会失败
Validity 有效期:Not Before / Not After 时间戳用 UTC,别用本地时间,否则跨时区翻车
Subject 主体 DN,标识证书持有者 mTLS 中 Subject 常用 CN(Common Name)做身份匹配
Subject Public Key Info 公钥算法 + 公钥值 椭圆曲线和 RSA 钥匙长度要满足当下安全要求
Extensions 扩展项,v3 特有 扩展错误可能导致浏览器/服务端拒签
Signature 证书签名,由颁发者私钥生成 签名验证是信任链的基石,不能跳过

记不记得我曾经说过证书链验证?根源就在这个 Signature 字段。颁发者用自己的私钥对证书内容签名,你拿着颁发者公钥验证,确认证书没被篡改。

扩展项:v3 证书的灵魂

为什么证书能做 mTLS 身份认证?全靠扩展项。x509 v3 引入了扩展,让证书不仅仅是一个“公钥包装”。

几个关键扩展,你一定得知道:

  • Basic Constraints – 标记证书是否为 CA。如果是 CA,还能指定路径长度。非 CA 设备证书必须设 CA:FALSE,否则有滥用风险。
  • Key Usage – 规定公钥用途:digitalSignature, keyEncipherment 等等。mTLS 服务端证书通常要同时允许签名和加密。
  • Extended Key Usage (EKU) – 更细粒度:serverAuth, clientAuth。微服务 mTLS 中,服务端证书必须有 serverAuth,客户端证书必须有 clientAuth。
  • Subject Alternative Name (SAN) – 替代主体名称。现在推荐用 SAN 而不是 CN 来存域名或 IP。单台服务器可能有多个域名,全放 SAN。
警告:我曾经因为 EKU 设置错误,导致服务端证书缺了 serverAuth,结果客户端发起 TLS 握手时直接被拒绝。排查了一下午才发现是证书签发脚本写错了。所以每一个扩展项的值,都要双检。

完整证书结构图

下面这张 SVG 图展示了 x509 v3 证书的整体骨架。从左到右,先分三块:证书基本信息、主体与公钥、扩展与签名。每一块里有哪些关键字段,一目了然。

X.509 v3 证书结构 基本信息 Version (v3) Serial Number Signature Algorithm Issuer DN Validity (NotBefore/After) Subject DN Subject Public Key Info Unique Identifiers (v2/v3) Extensions (v3 only) Signature (CA公钥验证) 扩展项(v3) ▪ Basic Constraints (CA:TRUE/FALSE) ▪ Key Usage (digitalSignature...) ▪ Extended Key Usage (serverAuth) ▪ Subject Alternative Name (SAN) ▪ CRL Distribution Points ▪ Authority Key Identifier ▪ Subject Key Identifier mTLS 场景用途 ▪ 服务端身份认证 (serverAuth) ▪ 客户端身份认证 (clientAuth) ▪ 证书链信任验证 ▪ 吊销检查 (OCSP/CRL) ▪ 公钥加密/数字签名 证书根节点 -> 签名 -> 完整性 证书中每个字段都有明确用途,扩展项更是mTLS安全策略的核心载体
核心要点: x509 v3 证书由三部分构成——固定字段(版本、序列号、有效期、颁发者、主体、公钥)、扩展项(基本约束、密钥用法、EKU、SAN)、以及签名(保证整体完整性)。mTLS 证书必须正确设置扩展项,才能实现双向认证。

实战中的检查清单

生成证书后,别急着部署。拿下面清单过一遍,能救你一命:

  1. 有效期 – 确保当前时间在 NotBefore 和 NotAfter 之间。我见过有人把日期写错成去年。
  2. Subject 与 SAN – 服务端证书的 SAN 必须包含客户端要连接的域名或 IP。mTLS 中多用 SAN 做匹配。
  3. EKU – 服务端证书要有 serverAuth;客户端证书要有 clientAuth。两者不能混。
  4. Basic Constraints – 非 CA 证书必须是 CA:FALSE。否则客户端可能会把它当作 CA 信任,导致中间人攻击。
  5. 签名算法 – 别用 MD5 或 SHA1。现在最低要求 SHA256-RSA 或 ECDSA。
我自己的经验: 用 openssl x509 -in cert.pem -purpose 可以快速检查证书用途是否匹配。这个命令会告诉你证书能做什么、不能做什么,比手撕 ASN.1 快多了。

x509 证书结构讲完了。记住,证书不是“公钥 + 签名”那么简单。扩展项才是微服务 mTLS 安全策略落地的关键。字段含义和扩展规则,一定要烂熟于心。