3. 自签名根证书:生成根证书私钥、创建自签名根证书、验证根证书内容

好,我们正式开始动手了。这一章要做的,就是整个证书链的「信任锚点」——自签名根证书。说白了,它就是那个没人给它签、它自己签自己的证书。你想想看,如果连根证书都不靠谱,那整个链上的所有证书都是空中楼阁。

我个人习惯把根证书的生成分成三步走:造私钥 → 签自己 → 验内容。每一步都有坑,我踩过不少,咱们一个一个来。

3.1 生成根证书私钥

私钥是根证书的命根子。丢了、泄露了、强度不够,后面全白搭。

我建议直接用 OpenSSL,它几乎是 PKI 领域的标配。命令很简单:

openssl genrsa -out ca-key.pem 4096

这里我用了 4096 位。为什么不用 2048?嗯,根证书一般有效期长(5年、10年甚至更久),密钥强度得留足余量。我在一个金融项目里见过用 2048 位根证书的,结果三年后合规审计要求升级到 4096,整个根要重新签发,那叫一个折腾。

我的习惯:根证书私钥一定要设置文件权限。Linux 下 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 验证根证书内容

证书生成完了,别急着用。先验验货。我一般用三个命令来检查:

  1. 看基本信息:
openssl x509 -in ca-cert.pem -text -noout

你会看到证书的版本、序列号、签名算法、颁发者、有效期、公钥信息等等。重点检查:

  • 颁发者和主题是否一致——自签名证书这两项必须一模一样。
  • 有效期——别生成出来就过期了(我见过有人把 -days 写成 1 的)。
  • 签名算法——推荐 SHA256,别用 SHA1(已经不安全了)。
  1. 验证自签名:
openssl verify -CAfile ca-cert.pem ca-cert.pem

如果输出 ca-cert.pem: OK,说明自签名验证通过。如果报错,那就要回头检查了。

  1. 查看指纹:
openssl x509 -in ca-cert.pem -fingerprint -sha256 -noout

指纹是证书的「数字摘要」,可以用来快速比对。我在部署时经常把指纹打印出来,跟对方口头核对一遍,防止中间人篡改。

3.4 根证书的核心结构

为了让你更直观地理解根证书内部长什么样,我画了一张图:

自签名根证书结构图 自签名根证书核心结构 基本信息 (TBSCertificate) • 版本号 (V3) • 序列号 (唯一) • 签名算法 (SHA256-RSA) • 颁发者 = 主题 (自签名) • 有效期 (10年) 公钥信息 • 算法: RSA • 密钥长度: 4096 位 • 模数 (Modulus) • 指数 (Exponent) • 公钥指纹 签名 (Signature) • 签名算法: SHA256-RSA • 签名值: 256 字节 • 用根私钥签名 • 验证用根公钥 扩展 (Extensions) • Basic Constraints: CA=TRUE • Key Usage: keyCertSign, cRLSign • Subject Key Identifier • Authority Key Identifier 关键点:自签名证书的 Issuer 和 Subject 完全相同,签名用自己的私钥,验证用自己的公钥

这张图把根证书拆成了四个核心块:基本信息、公钥、签名、扩展。你注意看,自签名证书的「颁发者」和「主题」是同一个实体,签名也是用自己的私钥签的。这就是「自签名」的本质。

3.5 避坑指南

我这些年踩过的坑,列几个典型的:

  • 私钥没设密码? 根证书私钥建议加 -aes256 加密。虽然每次用都要输密码,但安全多了。我曾经在测试环境忘了加密,结果被同事直接拷走……
  • 序列号重复? OpenSSL 默认随机生成序列号,但如果你手动指定 -set_serial,一定要保证唯一。序列号重复会导致客户端缓存冲突。
  • 扩展字段缺失? 根证书必须设置 CA:TRUE 和 keyCertSign,否则下级证书签出来浏览器不认。我见过有人用默认配置生成根证书,结果下级证书一直报「不信任的颁发者」。