3. 自签名根证书:生成根证书私钥、创建自签名根证书、验证根证书内容
好,我们正式开始动手了。这一章要做的,就是整个证书链的「信任锚点」——自签名根证书。说白了,它就是那个没人给它签、它自己签自己的证书。你想想看,如果连根证书都不靠谱,那整个链上的所有证书都是空中楼阁。
我个人习惯把根证书的生成分成三步走:造私钥 → 签自己 → 验内容。每一步都有坑,我踩过不少,咱们一个一个来。
3.1 生成根证书私钥
私钥是根证书的命根子。丢了、泄露了、强度不够,后面全白搭。
我建议直接用 OpenSSL,它几乎是 PKI 领域的标配。命令很简单:
openssl genrsa -out ca-key.pem 4096
这里我用了 4096 位。为什么不用 2048?嗯,根证书一般有效期长(5年、10年甚至更久),密钥强度得留足余量。我在一个金融项目里见过用 2048 位根证书的,结果三年后合规审计要求升级到 4096,整个根要重新签发,那叫一个折腾。
chmod 400 ca-key.pem,Windows 下也要限制访问。我曾经见过有人把私钥放在 777 的目录里……嗯,不说了。
生成完之后,你可以看一眼私钥的内容:
openssl rsa -in ca-key.pem -text -noout
你会看到模数(modulus)、指数(publicExponent)这些参数。重点检查一下模数的位数是不是 4096 位,别生成错了。
3.2 创建自签名根证书
私钥有了,接下来就是用这把钥匙给自己发一张「身份证」。这个过程叫自签名——证书的签发者和使用者都是自己。
命令长这样:
openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyLab/CN=MyLab Root CA v1"
解释一下关键参数:
| 参数 | 含义 | 我的建议 |
|---|---|---|
-x509 |
直接输出自签名证书,不走 CSR | 根证书专用,省一步 |
-days 3650 |
有效期 10 年 | 根证书建议 10-20 年,别太短 |
-subj |
主题信息(DN) | CN 一定要有辨识度,加版本号方便后续轮换 |
C=CN |
国家代码 | 按实际填写,别乱写 |
-subj 里的 CN(Common Name)是根证书的唯一标识。我见过有人把 CN 写成 "Root CA",结果后来签了两个不同版本的根证书,CN 一模一样,客户端根本分不清哪个是新的。建议加上版本号,比如 "MyLab Root CA v1"。
如果你想交互式填写 DN,也可以不加 -subj,OpenSSL 会弹出一堆问题。但我个人觉得,脚本化部署时还是用 -subj 更可控。
3.3 验证根证书内容
证书生成完了,别急着用。先验验货。我一般用三个命令来检查:
- 看基本信息:
openssl x509 -in ca-cert.pem -text -noout
你会看到证书的版本、序列号、签名算法、颁发者、有效期、公钥信息等等。重点检查:
- 颁发者和主题是否一致——自签名证书这两项必须一模一样。
- 有效期——别生成出来就过期了(我见过有人把
-days写成 1 的)。 - 签名算法——推荐 SHA256,别用 SHA1(已经不安全了)。
- 验证自签名:
openssl verify -CAfile ca-cert.pem ca-cert.pem
如果输出 ca-cert.pem: OK,说明自签名验证通过。如果报错,那就要回头检查了。
- 查看指纹:
openssl x509 -in ca-cert.pem -fingerprint -sha256 -noout
指纹是证书的「数字摘要」,可以用来快速比对。我在部署时经常把指纹打印出来,跟对方口头核对一遍,防止中间人篡改。
3.4 根证书的核心结构
为了让你更直观地理解根证书内部长什么样,我画了一张图:
这张图把根证书拆成了四个核心块:基本信息、公钥、签名、扩展。你注意看,自签名证书的「颁发者」和「主题」是同一个实体,签名也是用自己的私钥签的。这就是「自签名」的本质。
3.5 避坑指南
我这些年踩过的坑,列几个典型的:
- 私钥没设密码? 根证书私钥建议加
-aes256加密。虽然每次用都要输密码,但安全多了。我曾经在测试环境忘了加密,结果被同事直接拷走…… - 序列号重复? OpenSSL 默认随机生成序列号,但如果你手动指定
-set_serial,一定要保证唯一。序列号重复会导致客户端缓存冲突。 - 扩展字段缺失? 根证书必须设置
CA:TRUE和keyCertSign,否则下级证书签出来浏览器不认。我见过有人用默认配置生成根证书,结果下级证书一直报「不信任的颁发者」。