2、PKI体系基础:公钥基础设施概念、数字证书X.509标准、证书链信任模型
聊SM2证书链之前,得先把地基打牢。PKI这套东西,说白了就是解决一个核心问题:你怎么相信网络上那个自称是“张三”的人,真的是张三?
我早年做电子政务项目时,客户上来就问:“你们怎么保证我的公文没被篡改?”当时我给他画了个PKI的草图,他看完就懂了。嗯,今天咱们就把这张图画清楚。
2.1 公钥基础设施(PKI)概念
PKI不是某个软件,也不是某条命令。它是一套完整的规则、流程、软硬件和人员的组合。目标就一个:在开放网络环境中,安全地分发和管理公钥。
你想想看,非对称加密里,公钥本来就应该公开。但问题来了——你怎么知道你拿到的公钥,确实是对方的?中间人完全可以给你一个假公钥。PKI就是来解决这个信任问题的。
PKI的核心组成:
- CA(证书认证机构)——签发证书的权威机构,是整个信任体系的起点
- RA(注册机构)——负责审核用户身份,把审核结果告诉CA
- 证书库——存储和发布证书及CRL(证书吊销列表)的地方
- 终端实体——持有证书的用户或设备
- 管理协议——如CMP、SCEP,用于证书的申请、更新、吊销
我个人习惯把PKI比作“网络身份证系统”。CA就是公安局,RA就是派出所,证书就是身份证。你拿着身份证去办事,对方不用认识你本人,认身份证就行。
2.2 数字证书与X.509标准
数字证书就是PKI里的“身份证”。它把公钥和身份信息绑定在一起,再由CA盖上数字签名。这个签名一旦盖上,谁想篡改证书内容,签名验证就会失败。
目前最通用的证书格式是X.509 v3。我在项目中对接过不少国密设备,它们签发的SM2证书,本质上也是X.509 v3格式,只是签名算法换成了SM2withSM3。
2.2.1 X.509证书结构
一张标准的X.509 v3证书,包含以下字段:
| 字段 | 说明 | 我的备注 |
|---|---|---|
| 版本号 | 目前主流是v3(值为2) | v3才支持扩展项 |
| 序列号 | CA签发的唯一编号 | 吊销时靠它定位 |
| 签名算法 | 如SM2withSM3、SHA256withRSA | 国密场景就是SM2withSM3 |
| 颁发者 | 签发该证书的CA名称 | DN格式,如CN=SM2 Root CA |
| 有效期 | notBefore ~ notAfter | 注意时区问题 |
| 主体 | 证书持有者的名称 | 可以是个人、服务器、设备 |
| 主体公钥信息 | 算法标识 + 公钥值 | SM2公钥是65字节(未压缩) |
| 扩展项 | 密钥用法、基本约束、SAN等 | 证书链验证的关键 |
| CA签名 | CA用私钥对上述内容的签名 | 防篡改的核心 |
避坑指南:我曾经遇到一个案例,服务器证书的SAN(Subject Alternative Name)字段没配域名,结果浏览器一直报“证书名称不匹配”。查了两小时才发现是扩展项漏了。记住:现代浏览器优先看SAN,不看CN字段。
2.2.2 X.509 v3扩展项
扩展项是v3版本的精髓。没有扩展项,证书链就没法验证。几个关键扩展:
- 基本约束(BasicConstraints)——标记该证书是否为CA证书,以及路径长度限制
- 密钥用法(KeyUsage)——规定公钥用途,如数字签名、密钥加密
- 扩展密钥用法(ExtendedKeyUsage)——更细粒度,如服务器认证、客户端认证
- 主体密钥标识符(SubjectKeyIdentifier)——快速定位下一级证书的颁发者
- 颁发者密钥标识符(AuthorityKeyIdentifier)——指向上一级证书
为什么说这些重要?因为证书链验证时,每一步都要检查:上级CA证书是否允许签发下级证书?如果根CA证书的BasicConstraints没设CA标志,那它签发的所有子证书都是非法的。
2.3 证书链信任模型
单张证书好理解,但实际场景里,CA不会直接用根证书去签每个终端证书。为什么?安全考虑。根证书私钥一旦泄露,整个信任体系就崩了。所以通常采用多层证书链:
- 根CA——自签名,离线存储,极少使用
- 二级CA(中间CA)——由根CA签发,负责签发终端证书
- 终端实体证书——最终用户或服务器持有的证书
验证过程是从终端证书开始,逐级向上,直到找到一个自签名且受信任的根证书。这个路径就叫证书链。
注意:证书链验证不是简单的“上级签名下级”。它还要检查:
- 每张证书是否在有效期内
- 每张证书是否被吊销(查CRL或OCSP)
- 每张证书的密钥用法是否允许当前操作
- 路径长度是否超过BasicConstraints限制
下面这张图,是我当年给团队培训时画的。它清晰地展示了SM2证书链的信任传递过程:
这张图里,信任是自上而下传递的:根CA信任二级CA,二级CA信任终端实体。但验证是自下而上的:从终端证书开始,逐级向上验证签名,直到信任的根证书。
2.3.1 信任锚
信任锚(Trust Anchor)就是验证的终点。通常是一个预置在系统中的根证书。操作系统、浏览器、Java信任库都内置了一批根证书。国密场景下,需要把SM2根证书导入到系统的信任存储中。
我遇到过最头疼的问题是什么?某次对接政务平台,对方给了个SM2根证书,但格式是PEM,而我们的Java应用只认JKS。折腾了半天才转好。所以建议你提前确认好信任库的格式要求。
实用建议:在Linux系统中,SM2根证书可以放在 /etc/ssl/certs/ 目录下,然后运行 update-ca-certificates 更新信任库。如果是Java应用,用 keytool -importcert 导入到cacerts。
2.3.2 路径构建与路径验证
证书链验证分两步:路径构建和路径验证。
- 路径构建:从终端证书出发,根据颁发者信息,找到上一级证书,重复直到根证书。这一步可能有多条路径,需要选一条合法的。
- 路径验证:对选出的路径,逐级检查签名、有效期、吊销状态、密钥用法、基本约束等。
RFC 5280里把验证规则写得清清楚楚。但实际实现时,不同平台的细节有差异。比如OpenSSL和Java的证书路径构建算法就不完全一样。我建议你在开发阶段,用同一个库做验证,避免跨平台时出现“这边验证通过,那边验证失败”的尴尬。
2.4 国密SM2证书的特殊性
SM2证书遵循X.509 v3标准,但有几个国密特有的点:
| 项目 | 国际算法(RSA/ECC) | 国密SM2 |
|---|---|---|
| 签名算法OID | sha256WithRSAEncryption (1.2.840.113549.1.1.11) | sm2signWithSM3 (1.2.156.10197.1.501) |
| 公钥算法OID | rsaEncryption (1.2.840.113549.1.1.1) | sm2 (1.2.156.10197.1.301) |
| 椭圆曲线参数 | secp256r1等 | sm2p256v1 (固定曲线) |
| 签名值格式 | DER编码的SEQUENCE | DER编码的SEQUENCE(r,s) |
说白了,SM2证书就是把算法标识和曲线参数换成国密标准,其他结构完全兼容X.509。所以如果你已经熟悉国际证书,上手SM2证书很快。
重要提醒:SM2的椭圆曲线是固定的,参数由国家标准规定。不要试图用其他曲线生成SM2密钥对,否则证书解析时会报“无效曲线参数”。我见过有人用secp256r1冒充SM2,结果CA直接拒签。
2.5 小结
PKI体系的核心就三件事:谁签发(CA)、签给谁(证书)、怎么验证(证书链)。X.509 v3标准把证书结构定死了,扩展项给了灵活性。证书链信任模型通过分层CA,既保证了安全,又兼顾了效率。