2. X.509 证书标准:核心字段深度解析

X.509 证书,说白了就是数字世界里的身份证。我最早接触它的时候,觉得不就是个文件嘛,后来踩了坑才明白——证书里每个字段都有它的脾气。今天咱们就把这些字段掰开揉碎了讲清楚。

一句话总结:X.509 证书定义了公钥的归属关系,由 8 个核心字段和若干扩展项组成。理解这些字段,是证书链校验的基础。

2.1 证书版本(Version)

版本字段告诉你这个证书是哪个年代的产物。目前主流是 V3,V1 和 V2 基本绝迹了。

版本 值 特点
V1 0 最原始,不支持扩展项
V2 1 引入了颁发者和主体唯一标识符,但很少用
V3 2 当前标准,支持扩展项,功能最全

我的经验:我在项目中遇到过有人拿 V1 证书做 HTTPS,结果浏览器直接报错。因为 V1 不支持 SAN 扩展,现代浏览器根本不认。所以记住:生产环境只用 V3。

2.2 序列号(Serial Number)

序列号是 CA 给证书分配的唯一编号。它必须保证在同一个 CA 下唯一。

  • 长度:至少 8 字节,最多 20 字节
  • 随机性:我建议用强随机数生成,防止被预测
  • 作用:配合颁发者信息,可以唯一确定一张证书

避坑指南:我曾经见过一个系统,序列号直接用自增整数。结果攻击者通过枚举序列号,就能推断出 CA 签发了多少证书。这在 PKI 审计里是个大忌。

2.3 签名算法(Signature Algorithm)

这个字段告诉你怎么验证证书的签名。它和证书末尾的签名值必须一致。

常见的签名算法组合:

  • SHA256WithRSA — 目前最主流
  • SHA256WithECDSA — 椭圆曲线,密钥更短
  • SHA1WithRSA — 已废弃,别用了

注意:签名算法字段和签名算法标识符是两个东西。前者是 OID,后者包含算法和参数。我见过有人搞混,导致解析失败。

2.4 颁发者(Issuer)

颁发者就是签发这张证书的 CA 的身份信息。它用 DN(Distinguished Name)表示。

一个典型的 DN 长这样:

CN = My Root CA
O  = My Company
C  = CN

关键点:

  • 证书链校验时,子证书的 Issuer 必须匹配父证书的 Subject
  • 根证书的 Issuer 和 Subject 通常是相同的(自签名)

2.5 有效期(Validity)

有效期包含两个时间点:notBefore 和 notAfter。

我个人的习惯是:

  • 服务器证书:1-2 年
  • 中间 CA 证书:5-10 年
  • 根证书:10-20 年

我曾经踩过的坑:有一次系统时间没同步,导致刚签发的证书显示已过期。你想想看,证书本身没问题,但校验时直接挂了。所以 NTP 时间同步是 PKI 的基础设施。

2.6 主体(Subject)

主体就是证书持有者的身份。对于服务器证书,通常用域名做 CN。

举个例子:

Subject: CN = www.example.com, O = Example Inc., C = US

但这里有个坑——现代浏览器已经不拿 CN 做域名匹配了。它们只看 SAN 扩展。所以 CN 现在更多是个标识作用。

2.7 公钥信息(Subject Public Key Info)

这是证书的核心——包含了公钥算法和公钥值。

算法 密钥长度 适用场景
RSA 2048 / 4096 通用,兼容性最好
ECDSA 256 / 384 性能好,密钥短
Ed25519 256 新兴,速度快

我的建议:新系统优先用 ECDSA。RSA 4096 虽然安全,但握手时计算量太大。我在一个高并发网关项目里,把 RSA 换成 ECDSA 后,TLS 握手性能提升了 30%。

2.8 扩展项(Extensions)

V3 证书的精髓就在扩展项。没有它们,证书就是个空壳。咱们重点讲三个最关键的。

2.8.1 密钥用法(Key Usage)

这个扩展限制了公钥能干什么。比如:

  • digitalSignature — 用于签名验证
  • keyEncipherment — 用于密钥交换
  • keyCertSign — 用于签发证书(只有 CA 证书才有)

关键规则:如果证书没有 keyCertSign 标记,它就不能用来签发其他证书。这是防止权限滥用的第一道防线。

2.8.2 基本约束(Basic Constraints)

这个扩展告诉系统:这张证书是不是 CA 证书。

BasicConstraints: CA:TRUE
  — 这是 CA 证书,可以签发子证书
BasicConstraints: CA:FALSE
  — 这是终端实体证书,不能签发

我见过最严重的生产事故,就是有人把终端证书的 CA 标记设成了 TRUE。结果这个证书可以随意签发子证书,整个 PKI 体系瞬间崩塌。

2.8.3 主体备用名称(Subject Alternative Name, SAN)

SAN 是现代 PKI 的核心。它列出了证书可以用于哪些域名。

举个例子:

DNS: example.com
DNS: www.example.com
DNS: api.example.com

没有 SAN 的证书,浏览器会报安全警告。所以签发证书时,一定要把需要的域名都列进去。

避坑指南:我曾经帮一个客户排查证书问题,发现他们给 www.example.com 签了证书,但用户访问 example.com(不带 www)时却报错。原因就是 SAN 里只写了 www.example.com,没写 example.com。记住:SAN 不会自动补全父域名。

2.9 知识体系总览

下面这张图把 X.509 证书的核心结构串起来了。我建议你保存下来,以后看证书时对照着看。

X.509 V3 证书结构 基本信息(必填) 版本 (V3) | 序列号 (唯一标识) 签名算法 (SHA256WithRSA) 颁发者 (Issuer DN) 有效期 (notBefore → notAfter) 主体信息(必填) 主体 (Subject DN) 公钥信息 算法: RSA/ECDSA | 密钥值 颁发者唯一标识 (V2+) 扩展项(V3 可选,但现代 PKI 必用) 密钥用法 • digitalSignature • keyEncipherment • keyCertSign (CA专用) 基本约束 • CA:TRUE / FALSE • pathLenConstraint 控制证书链深度 SAN • DNS: example.com • IP: 192.168.1.1 域名匹配的唯一依据 CA 签名值(用颁发者的私钥对以上所有字段签名)

2.10 小结

X.509 证书的每个字段都不是摆设。版本决定了能力,序列号保证了唯一性,签名算法和公钥信息构成了安全基础,而扩展项则赋予了证书灵活性。

我个人觉得,理解这些字段最好的方式就是拿一张真实证书来解析。用 OpenSSL 命令看看:

openssl x509 -in cert.pem -text -noout

你会看到上面讲的所有字段。下次遇到证书问题,别慌,按这个结构逐项排查,基本都能找到根因。