4. 生成根证书:创建自签名根CA,配置有效期与密钥强度
好,咱们进入实战环节。前面几章我们把证书链的骨架搭好了,现在要亲手造出整条链的「信任之根」——根CA证书。
根证书是整个PKI体系的基石。它要是出了问题,下面签发的所有证书都得跟着完蛋。我见过不少团队,根证书随便拿个默认参数就生成了,结果后面要么密钥强度不够被破解,要么有效期设得太短导致大规模重新部署。嗯,咱们今天就把这事做扎实。
4.1 根证书的核心定位
先想清楚一个问题:根证书到底扮演什么角色?
- 自签名:没有上级CA给它背书,它自己证明自己
- 信任锚点:设备出厂时预置的就是它,所有下级证书的合法性最终都追溯到它
- 离线保管:根CA的私钥应该放在离线环境,平时签发用中间CA
说白了,根证书就是你家大门的总锁芯。锁芯质量不行,再好的门锁都没用。
核心原则:根证书的密钥强度必须高于或等于所有下级证书。我个人习惯根密钥至少比中间CA大一个安全等级。
4.2 密钥强度怎么选?
这里我直接给结论,都是我在项目中踩过坑之后总结出来的。
| 算法 | 推荐强度 | 安全年限(预估) | 适用场景 |
|---|---|---|---|
| RSA | 4096位 | 2030年前安全 | 通用嵌入式设备 |
| ECDSA | P-384 | 2030年前安全 | 资源受限设备 |
| Ed25519 | 256位 | 长期安全 | 新设计推荐 |
为什么我不推荐RSA 2048?因为很多嵌入式设备生命周期长达10年,2048位在2030年后可能就不够看了。你想想看,设备部署出去之后,总不能为了换根证书派人去现场刷机吧?
注意:我曾经接手过一个项目,根证书用的RSA 1024位。当时觉得够用,结果三年后就被爆出1024位RSA存在实际破解风险。最后不得不紧急OTA升级整个证书链,那叫一个折腾。
4.3 有效期怎么设?
有效期是个两难问题:
- 太短:频繁更换根证书,部署成本高
- 太长:密钥泄露风险累积,且无法利用新算法
我个人建议:根证书有效期10年,中间CA 5年,终端证书2-3年。这样即使中间CA泄露,根证书还在,可以重新签发中间CA。
为什么会这样设计?因为根证书的私钥平时锁在保险柜里,基本不碰它。中间CA和终端证书才是在线使用的,风险更高。
4.4 实战:用OpenSSL生成根证书
好,咱们动手。以下是我在项目中反复使用的脚本,每一步都有讲究。
4.4.1 准备目录结构
mkdir -p ca/root-ca/private ca/root-ca/certs ca/root-ca/newcerts
touch ca/root-ca/index.txt
echo 1000 > ca/root-ca/serial
这个结构不是随便建的。index.txt用来记录签发的证书,serial文件控制证书序列号。我见过有人直接手动指定序列号,结果重复了,整个CA的证书链乱成一锅粥。
4.4.2 生成根CA私钥
openssl genrsa -aes256 -out ca/root-ca/private/ca.key.pem 4096
这里几个要点:
-aes256:私钥用AES-256加密存储,需要密码才能使用4096:密钥长度,前面说了,这是底线- 权限设置:
chmod 400 ca/root-ca/private/ca.key.pem
小技巧:私钥密码一定要记牢,但别写在代码注释里。我习惯用密码管理器生成一个32位随机密码,然后打印两份纸质版分别存放。
4.4.3 生成根证书(自签名)
openssl req -new -x509 -days 3650 \
-key ca/root-ca/private/ca.key.pem \
-out ca/root-ca/certs/ca.cert.pem \
-subj "/C=CN/O=MyCompany/CN=MyRootCA" \
-extensions v3_ca
参数说明:
-x509:直接输出自签名证书,不走CSR流程-days 3650:10年有效期-extensions v3_ca:启用v3扩展,后面配置关键属性
4.4.4 配置v3扩展(关键!)
创建一个配置文件ca/root-ca/openssl.cnf:
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
[ req_distinguished_name ]
countryName = CN
organizationName = MyCompany
commonName = MyRootCA
[ v3_ca ]
basicConstraints = critical, CA:TRUE, pathlen:1
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
这里我重点解释两个:
- basicConstraints:
CA:TRUE表示这是CA证书,pathlen:1限制下级CA只能再签一级 - keyUsage:只允许用来签发证书和CRL,不能用来做TLS加密或数字签名
避坑指南:我曾经见过有人把根证书的keyUsage设成了digitalSignature, keyEncipherment,结果根证书被当成了服务器证书使用。虽然功能上没问题,但违背了最小权限原则。根证书就应该只干一件事:签发下级证书。
4.5 验证根证书
生成完了别急着用,先验证一下:
openssl x509 -in ca/root-ca/certs/ca.cert.pem -text -noout
重点检查:
- Issuer和Subject是否一致(自签名)
- 有效期是否正确
- basicConstraints是否包含CA:TRUE
- keyUsage是否只有keyCertSign和cRLSign
4.6 根证书的存储与备份
根证书生成后,要做三件事:
- 私钥离线存储:拷贝到U盘或加密卡,锁进保险柜
- 证书分发:根证书(不含私钥)可以公开,预置到所有设备中
- 备份:至少做两份物理备份,异地存放
我的做法:根私钥用硬件安全模块(HSM)存储,同时打印一份QR码形式的私钥密文备份。QR码放在银行保险柜里。听起来夸张?等你遇到硬盘损坏、U盘丢失的时候就知道这有多重要了。
4.7 本章知识体系
下面这张图把根证书生成的核心逻辑串起来了:
4.8 常见问题
Q:根证书的CN(Common Name)应该填什么?
A:填一个能唯一标识你的组织的名称,比如公司域名或品牌名。不要填个人名字,因为根证书要管10年,人员会变动。
Q:能不能用同一个根证书签多个中间CA?
A:可以,而且这是推荐做法。比如一个中间CA用于生产环境,另一个用于测试环境。但每个中间CA的pathlen要控制好。
Q:根证书过期了怎么办?
A:这就是为什么我强调要提前规划。在根证书到期前一年,就要开始准备新的根证书,并通过OTA或现场升级的方式部署到所有设备。新旧根证书可以并行运行一段时间,等所有设备都更新后再废弃旧的。
个人经验:我习惯在根证书到期前18个月就启动迁移计划。因为嵌入式设备分布广、网络条件差,有些设备可能半年都连不上一次网。留足缓冲时间,避免出现设备变成「孤儿」的情况。