2. 证书标准与结构:X.509标准详解、证书字段解析、证书编码格式
聊到证书,绕不开的就是 X.509 标准。说实话,我入行那会儿,觉得这玩意儿就是个「死标准」,背下来就行了。直到后来在项目中踩了坑,才明白——不理解 X.509,你连证书为什么过期、为什么吊销都搞不清楚。
这一节,咱们就把 X.509 扒开来看。我会结合自己这些年遇到的真实案例,帮你把证书的「骨架」和「血肉」理清楚。
2.1 X.509 标准:证书世界的通用语言
X.509 是国际电信联盟(ITU-T)定义的一个公钥证书格式标准。说白了,它就是一套「证书长什么样」的规范。你用的 HTTPS、代码签名、电子邮件加密,底层都是 X.509 证书。
我经常跟团队说一句话:「X.509 就是证书界的普通话」。不管你是 OpenSSL 签的,还是企业 CA 发的,只要遵循这个标准,大家就能互相认。
核心要点:X.509 v3 是目前最广泛使用的版本。v1 和 v2 基本已经淘汰了,别再用。
我记得有一次,一个客户拿了个 v1 证书过来,说「为什么浏览器报错?」我一看,这证书还是 1999 年签的。嗯,浏览器不认 v1 的扩展字段,自然报不安全。
2.2 证书字段解析:一张证书里到底写了什么?
一张 X.509 证书,本质上就是一个结构化的数据对象。咱们把它拆开来看,每个字段都有它的使命。
下面这张图,是我自己画的一个证书结构总览。你可以把它当作「地图」,后面讲每个字段时,随时回来对照。
2.2.1 版本(Version)
版本字段告诉你这张证书用的是 X.509 的哪个版本。目前主流是 v3(值为 2)。v1(值为 0)和 v2(值为 1)基本绝迹了。
为什么 v3 是主流? 因为 v3 引入了扩展字段。没有扩展,你就没法做 SAN(主题备用名称)、没法做密钥用法约束。说白了,v3 让证书变得「灵活」了。
2.2.2 序列号(Serial Number)
序列号是 CA 给每张证书分配的唯一编号。它必须唯一,不能重复。我见过一个坑:某个 CA 的序列号生成器出了 bug,重复了。结果吊销证书时,CRL 里分不清哪张是哪张。
注意:序列号必须是正整数,且至少 8 字节。RFC 5280 建议用 20 字节,防止碰撞。
2.2.3 签名算法(Signature Algorithm)
这个字段告诉你怎么验证这张证书的签名。比如 sha256WithRSAEncryption 或 ecdsa-with-SHA256。
我个人习惯,看到 SHA-1 签名的证书直接打回。SHA-1 已经不安全了,2017 年 Google 就演示了碰撞攻击。你想想看,如果你的证书还在用 SHA-1,攻击者完全可以伪造一张一模一样的。
2.2.4 颁发者(Issuer)和主体(Subject)
这两个字段是 DN(Distinguished Name,专有名称)。颁发者是 CA 的身份,主体是证书持有者的身份。
举个例子:
颁发者: CN=MyCA, O=MyCompany, C=CN
主体: CN=www.example.com, O=Example Inc, C=CN
我曾经在项目中遇到一个问题:主体 CN 写的是 example.com,但浏览器访问的是 www.example.com。结果浏览器报证书名称不匹配。嗯,这就是典型的「主体名称没对齐」。
2.2.5 有效期(Validity)
包含两个时间戳:生效时间(notBefore) 和 失效时间(notAfter)。证书只在两者之间有效。
我建议你注意一个细节:时钟同步。服务器时间不准,证书可能「提前过期」或「尚未生效」。我在一个金融项目里遇到过,NTP 服务挂了,所有证书验证都失败。排查了半小时才发现是时间问题。
2.2.6 公钥信息(Subject Public Key Info)
这是证书的核心——持有者的公钥。包含算法(RSA、ECDSA 等)和公钥值。
你想想看,别人拿到这张证书,就是用这个公钥来加密数据或验证签名的。如果公钥泄露,证书就得吊销。
2.2.7 扩展(Extensions)—— v3 的灵魂
扩展字段是 v3 最大的亮点。没有它,证书就是个「死板」的身份证明。常见的扩展有:
| 扩展名称 | OID | 作用 |
|---|---|---|
| 基本约束 (Basic Constraints) | 2.5.29.19 | 标记是否为 CA 证书 |
| 密钥用法 (Key Usage) | 2.5.29.15 | 限制密钥用途(签名、加密等) |
| 主题备用名称 (SAN) | 2.5.29.17 | 列出证书适用的域名/IP |
| CRL 分发点 (CRL Distribution Points) | 2.5.29.31 | 告诉你去哪里下载吊销列表 |
| 颁发机构信息访问 (AIA) | 1.3.6.1.5.5.7.1.1 | 提供 CA 证书和 OCSP 地址 |
避坑指南:我曾经遇到一个案例,SAN 里只写了 example.com,但用户访问的是 www.example.com 和 mail.example.com。结果浏览器报错。记住:SAN 必须包含所有实际使用的域名。
2.3 证书编码格式:DER 与 PEM
证书在计算机里怎么存?两种主流格式:DER 和 PEM。
2.3.1 DER 格式
DER(Distinguished Encoding Rules)是二进制格式。它是 ASN.1 编码的一种。说白了,就是机器读的,人看不懂。
DER 文件通常以 .cer、.crt、.der 为后缀。你在 Windows 上双击一个 .cer 文件,看到的就是 DER 解码后的内容。
2.3.2 PEM 格式
PEM(Privacy Enhanced Mail)是文本格式。它把 DER 二进制数据用 Base64 编码,再加上头尾标记。
一个 PEM 证书长这样:
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIU...
(中间是 Base64 编码的数据)
-----END CERTIFICATE-----
PEM 的好处是:可以复制粘贴,可以放在邮件里,可以嵌入代码。我个人习惯,所有证书文件都用 PEM 格式存。DER 只在系统底层交互时用。
2.3.3 格式转换
你经常需要在两种格式之间转换。OpenSSL 是标配工具:
# DER 转 PEM
openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM
# PEM 转 DER
openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
经验之谈:我建议你统一用 PEM 格式。DER 是二进制,肉眼没法检查。PEM 可以用文本编辑器打开,至少能看一眼头尾标记对不对。
2.4 如何查看证书内容?
拿到一张证书,怎么知道里面写了什么?用 OpenSSL 的 x509 命令:
# 查看 PEM 证书的文本内容
openssl x509 -in cert.pem -text -noout
# 查看 DER 证书
openssl x509 -in cert.der -inform DER -text -noout
输出会包含所有字段:版本、序列号、签名算法、颁发者、有效期、主体、公钥、扩展等。
我经常用这个命令来快速验证一张证书。比如检查 SAN 有没有写对,或者看有效期还剩多久。
注意:不要只看文件名就信任证书。我曾经收到一个文件叫 trusted.cer,打开一看,SAN 是 evil.com。文件名可以随便改,内容才是关键。
2.5 小结
这一节我们拆解了 X.509 证书的每个字段,也聊了 DER 和 PEM 两种编码格式。你想想看,理解了这些,你就能看懂一张证书的「身份证」了。