数字证书:X.509证书结构、证书链、证书扩展域

好,我们接着聊。前面说了CRL和证书吊销,但你拿到一个证书的时候,怎么知道它是真的?这就得靠我们今天要讲的X.509证书结构、证书链和证书扩展域。说白了,这就是数字世界的「身份证」体系。

X.509证书结构:一张身份证的各个栏目

我敢打赌,大家都看过自己的身份证。正面有姓名、头像、有效期,背面有发证机关。X.509证书,就是这么一张数字身份证。它的标准版本是v3,我平时接触的证书大部分都是这个版本。

来看看证书里到底塞了哪些字段,我挑几个关键的讲:

字段 说明 项目中的坑
版本号 目前主流是v3,v1和v2基本淘汰 遇到老旧CA还可能签发v1,记得检查
序列号 CA给这张证书的唯一编号 吊销时就是靠这个序列号找证书
签名算法 CA签名时用的算法,比如SHA256-RSA 千万别用SHA1,不够安全
颁发者 签发这张证书的CA名字 我见过跨域证书这里填错的
有效期 生效和失效时间 曾经有个系统没检查notBefore
主体 证书持有者的身份,比如域名或人名 CN和SAN必须匹配,否则浏览器报错
公钥 持有者的公钥 位数够别低于2048位
扩展域 v3新增的灵活功能 下面会重点讲
我的习惯:每次拿到一张未知证书,先对着OpenSSL输出的文本一行行扫一遍,特别关注有效期和扩展域。踩过太多次坑,现在条件反射了。

证书链:谁给谁做担保?

你想想看,如果每个网站都自己发证书,你信吗?肯定不信。所以有了证书链。

证书链,说白了就是一层层担保。根CA是最顶级的信任锚点,它签发中间CA,中间CA再签发服务器证书。这样就形成了一个链条。

为什么要有中间CA?我理解是为了安全隔离。根CA的私钥要是泄露,整个体系就崩了。所以通常根CA离线上,中间CA干活。

我自己做项目时,最喜欢用openssl命令查看证书链:

openssl s_client -connect example.com:443 -showcerts

你会看到一串证书,从上到下分别是:服务器证书、中间CA证书、根证书。有些服务器会漏发中间CA,这时我就得手动去CA官网下载补上。

层级 信任起点 签发者 用途
根CA 自签名 自己 信任锚点,离线保护
中间CA 根CA 上级CA 日常签发证书
最终实体证书 中间CA 签发CA 网站/用户身份
我曾经踩过的坑:有一次部署HTTPS,浏览器一直提示证书错误。排查了半天,发现是中间CA证书没传。很多项目都犯这错,记住:服务器要发送完整链路,从服务器证书到根证书(根一般不传,但中间必须传)。

证书扩展域:v3证书的杀手锏

v3之前的证书很死板,v3加入了扩展域,功能立刻活了起来。扩展域是个标准化的区域,可以定义很多额外属性。

我挑几个最常用的扩展域说说:

  • 基本约束 (Basic Constraints):标记证书是不是CA,以及可以签发多少下级证书。我见过有人把服务器证书也标记成CA,赶紧改过来。
  • 密钥用法 (Key Usage):限制公钥能干的事,比如digitalSignature、keyEncipherment。少一个就可能报错。
  • 扩展密钥用法 (Extended Key Usage):更细粒度,比如serverAuth只能用于服务器,clientAuth只能用于客户端登录。
  • 主题备用名称 (Subject Alternative Name, SAN):这个太重要了。现代浏览器基本只看SAN,不看CN。你可以一个证书包含多个域名。
  • CRL分发点 (CRL Distribution Points):告诉你CRL在哪里下载,跟我们课程主标题相关。以后专门讲。
  • 授权信息访问 (Authority Information Access, AIA):获取颁发者证书和OCSP服务地址。
避坑指南:扩展域不是摆设,写错或者漏写,证书验证直接失败。我曾经在一个项目中,漏写了SAN,结果所有浏览器都报「证书名称不匹配」。后来加上了SAN才解决。

知识结构图:一次看明白

下面的图,把证书结构、证书链和扩展域串在一起了。你一看就明白。

X.509证书核心概念关系图 证书结构 版本号 / 序列号 颁发者 / 主体 有效期 / 公钥 签名算法 证书链 根CA(自签名) 中间CA(一层或多层) 最终实体证书 证书扩展域 基本约束 密钥用法 / 扩展密钥用法 SAN / CRL分发点 / AIA 三者关系:证书结构是骨骼,证书链是层级信任,扩展域是灵活功能 当一个证书通过CRL分发点检查时,需要用到三者协作 举个例子,验证一个网站证书: 1. 解析证书结构,读取颁发者、有效期、SAN 2. 沿着证书链向上找到信任的根CA 3. 通过CRL分发点扩展域下载CRL,检查是否吊销

所以,你看到一张数字证书,别光看内容。你要懂它的结构,才能明白哪些字段能信。你要懂证书链,才知道它背后的靠山是谁。你要懂扩展域,才知道它能干什么事、不能干什么事。

多提一嘴:我自己习惯在部署SSL/TLS前,先用OpenSSL把所有扩展域打印一遍。特别是SAN和EKU,这两个最容易导致线上故障。记住了。