X.509 标准详解:证书的“身份证”长什么样
说实话,搞安全这么多年,我见过太多因为不理解 X.509 结构而翻车的案例。有人把序列号写死成固定值,有人把有效期设成 100 年,还有人把扩展域乱填一气。嗯,这些坑我都踩过。
X.509 标准,说白了就是定义了数字证书的格式。你拿到的每一张 SSL/TLS 证书,本质上都是一个 X.509 结构体。今天我就带你把它拆开看看,每个字段到底在干什么。
一句话总结:X.509 证书 = 身份信息 + 公钥 + 签名 + 一堆扩展属性。浏览器信任它,是因为有 CA 在背后背书。
2.1 证书版本:V1、V2、V3 的区别
版本字段只有 0、1、2 三个值,分别对应 V1、V2、V3。现在你几乎见不到 V1 和 V2 的证书了,为什么?
- V1(版本 0):最原始,只有基本字段,没有扩展域。我十年前在某个老系统里见过,现在基本绝迹。
- V2(版本 1):加了颁发者和使用者唯一标识符。说实话,这俩字段后来基本没人用。
- V3(版本 2):这才是现代证书的标配。引入了扩展域,支持 SAN(主题备用名称)、密钥用法、证书策略等关键信息。
我的习惯:所有新生成的证书一律用 V3。别问为什么,问就是扩展域太重要了,后面你会明白。
2.2 序列号:唯一标识,别偷懒
序列号是 CA 给每张证书分配的唯一编号。它必须唯一,而且我建议你让它看起来随机一点。
为什么?我曾经见过一个项目,序列号直接用自增整数 1、2、3……结果被攻击者猜到了下一张证书的序列号,配合其他漏洞搞出了证书伪造。嗯,从那以后我再也不敢用简单序列号了。
| 要求 | 说明 |
|---|---|
| 唯一性 | 同一 CA 下不能重复 |
| 随机性 | 至少 20 位随机字节,避免可预测 |
| 编码 | 使用正整数,ASN.1 INTEGER 类型 |
2.3 签名算法:用什么算法签的名
这个字段告诉你怎么验证这张证书。常见的有 sha256WithRSAEncryption、ecdsa-with-SHA256 等。
注意,这里有个坑:签名算法字段和证书末尾的签名值必须一致。我见过有人算法字段写 SHA256,实际签名用的 SHA1,结果验证直接挂掉。你想想看,这种低级错误一旦上线,排查起来多痛苦。
避坑指南:我曾经在迁移证书时,忘了更新签名算法 OID,导致所有客户端握手失败。后来我写了个脚本,每次签发前自动校验算法字段和签名值是否匹配。建议你也这么做。
2.4 颁发者与使用者:谁签的,给谁的
这两个字段都是 Distinguished Name(DN),包含国家、组织、通用名称等信息。
- 颁发者(Issuer):签发这张证书的 CA 的身份。
- 使用者(Subject):这张证书归属的实体身份。
如果是自签名证书,颁发者和使用者一模一样。根证书就是这样。但在中间证书里,颁发者是上级 CA,使用者是下级 CA 或终端实体。
关键点:浏览器验证证书链时,会检查上一级证书的 Subject 是否等于下一级证书的 Issuer。这个链条一旦断裂,就会报“证书链不完整”。
2.5 有效期:别让证书过期了还不知道
有效期由两个时间戳组成:notBefore 和 notAfter。前者是生效时间,后者是过期时间。
我个人习惯把有效期设成 1 年。太长不安全,太短运维累。有些公司设 3 个月,配合自动化续签,也挺好。
但要注意:客户端的时间必须准确。我遇到过一台服务器时间慢了 5 分钟,结果证书刚签发就显示“未生效”。排查了半天,最后发现是 NTP 没配好。你说冤不冤?
2.6 公钥信息:核心中的核心
这个字段包含两部分:公钥算法和公钥值。RSA 的话就是模数 n 和指数 e;ECC 的话就是曲线参数和公钥点。
公钥长度现在建议至少 2048 位(RSA)或 256 位(ECC)。1024 位的 RSA 已经被证明不够安全了,我建议你直接放弃。
| 算法 | 最小安全长度 | 推荐长度 |
|---|---|---|
| RSA | 2048 位 | 3072 或 4096 位 |
| ECDSA | 256 位(P-256) | 384 位(P-384) |
| EdDSA | 256 位(Ed25519) | Ed25519 或 Ed448 |
2.7 扩展域:V3 证书的灵魂
扩展域是 V3 证书最强大的地方。它让证书不再只是一个“公钥+身份”的简单结构,而是变成了一个可编程的安全载体。
常见的扩展域有:
- Basic Constraints:标记是否为 CA 证书。这个设错了,中间证书就能签发任意域名,后果很严重。
- Key Usage:限制密钥用途,比如 digitalSignature、keyEncipherment。
- Extended Key Usage:更细粒度的用途,比如 serverAuth、clientAuth。
- Subject Alternative Name (SAN):这才是现代浏览器真正看的域名。Common Name 已经退居二线了。
- CRL Distribution Points:证书吊销列表的获取地址。
- Authority Information Access:CA 颁发者信息,包括 OCSP 响应地址。
血的教训:我曾经漏配了 SAN 扩展,结果 Chrome 直接报“NET::ERR_CERT_COMMON_NAME_INVALID”。从 Chrome 58 开始,浏览器已经不再信任 Common Name 了,SAN 是必填项。切记!
知识体系总览
下面这张图把 X.509 证书的核心结构串起来了。你可以把它当作一个检查清单,签发或验证证书时对照着看。
小结
X.509 证书的每个字段都不是摆设。版本决定了你能用哪些特性,序列号要随机,签名算法要和签名值匹配,颁发者和使用者构成信任链,有效期要合理,公钥要够长,扩展域要配全。
我个人建议你每次签发证书前,都拿这张结构图对照一遍。尤其是扩展域,漏一个 SAN 就可能让整个证书废掉。嗯,这些细节,就是专业和业余的分水岭。