4、根证书颁发机构(CA)搭建:生成CA私钥、生成CA自签名根证书、配置CA工作目录、验证根证书
说实话,搭建自己的根CA,是很多人学习PKI时最兴奋的一步。我记得自己第一次在实验室里敲完命令,看到那个自签名证书生成成功时,心里还挺有成就感的。但后来在生产环境里踩过几次坑,才明白这一步看似简单,实则处处是细节。
咱们今天就把根CA搭建这件事,掰开揉碎了讲清楚。你跟着我走一遍,以后不管是在内网做设备认证,还是给微服务配mTLS,心里都有底。
4.1 整体流程概览
搭建根CA,说白了就是四步走:
- 生成CA私钥 —— 这是CA的“身份证”,必须保管好
- 生成自签名根证书 —— 用私钥给自己签一张证书
- 配置CA工作目录 —— 让OpenSSL知道文件放哪、怎么管理
- 验证根证书 —— 确认证书能用、没毛病
这四步环环相扣。私钥丢了,证书就是废纸;目录配错了,后面签发子证书时会报一堆莫名其妙的错。我见过有人跳过第三步,直接手动管理文件,结果三个月后自己都找不到证书序号文件在哪。
4.2 生成CA私钥
私钥是CA的命根子。我习惯用 aes256 加密私钥文件,这样就算文件泄露了,没有密码也白搭。
核心命令:
# 生成4096位RSA私钥,用AES-256加密
openssl genrsa -aes256 -out ca-key.pem 4096
执行后会让你输入一个密码。这里我多说一句:密码别用生日、公司名这种。我在一个项目里见过有人设了 ca123456,结果被内部审计直接打回。建议用至少16位,大小写+数字+特殊字符。
我的习惯:私钥文件权限设为 400(仅所有者可读)。曾经有个同事把私钥权限设成 644,被CI/CD工具误读到日志里……嗯,那场面挺尴尬的。
chmod 400 ca-key.pem
4.3 生成自签名根证书
有了私钥,下一步就是给自己发一张“身份证”。这里要用到 openssl req 命令,加上 -x509 参数表示自签名。
生成根证书:
openssl req -new -x509 -days 3650 \
-key ca-key.pem \
-out ca-cert.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyLab/CN=MyLab Root CA"
参数说明:
| 参数 | 含义 | 建议值 |
|---|---|---|
-days 3650 |
证书有效期(天) | 根证书建议10年(3650天) |
-subj |
证书主体信息 | CN必须唯一标识你的CA |
-x509 |
生成自签名证书 | 根CA必须用此参数 |
注意:根证书的有效期不要设太短。你想想看,如果根证书过期了,它下面签发的所有子证书都会失效。我建议至少10年,甚至20年也行。但别设成 -days 0,那证书当天就过期……别问我怎么知道的。
4.4 配置CA工作目录
这一步很多人会忽略,但恰恰是生产环境里最容易出问题的地方。OpenSSL需要一个标准的工作目录结构来管理证书签发记录。
我个人习惯用 /root/ca 作为根目录,结构如下:
mkdir -p /root/ca/{certs,crl,newcerts,private}
chmod 700 /root/ca/private
touch /root/ca/index.txt
echo 1000 > /root/ca/serial
每个目录的用途:
| 目录/文件 | 作用 |
|---|---|
certs/ |
存放已签发的证书文件 |
crl/ |
存放证书吊销列表 |
newcerts/ |
OpenSSL自动生成的证书副本 |
private/ |
存放CA私钥(权限必须700) |
index.txt |
证书签发数据库,记录每张证书的状态 |
serial |
下一个证书的序列号 |
避坑指南:我曾经在配置 openssl.cnf 时,忘了指定 dir 路径,结果OpenSSL默认用当前目录。后来签了50多张证书,想吊销一张时发现 index.txt 是空的……从那以后,我每次建CA都会先检查 openssl.cnf 里的路径配置。
这里给一份最简的 openssl.cnf 配置,放在 /root/ca/openssl.cnf:
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /root/ca
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
private_key = $dir/private/ca-key.pem
certificate = $dir/ca-cert.pem
default_md = sha256
policy = policy_loose
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
4.5 验证根证书
证书生成完了,目录也配好了,最后一步就是验证。别偷懒,这一步能帮你发现80%的配置错误。
验证命令:
# 查看证书基本信息
openssl x509 -in ca-cert.pem -text -noout
# 验证自签名(根证书自己验证自己)
openssl verify -CAfile ca-cert.pem ca-cert.pem
重点关注输出中的几个字段:
- Issuer 和 Subject 必须相同 —— 这是自签名的标志
- Validity 日期范围是否正确
- Signature Algorithm 应该是
sha256WithRSAEncryption - X509v3 Basic Constraints 必须包含
CA:TRUE
重要:如果 openssl verify 返回 error 18 at 0 depth lookup: self signed certificate,别慌。这是根证书自签名的正常提示,表示“这个证书是自己签自己,不是由上级CA签发的”。只要没有 error 10(证书过期)或 error 20(无法获取本地颁发者证书),就没问题。
我习惯再用一条命令确认证书的CA能力:
openssl x509 -in ca-cert.pem -noout -ext basicConstraints
输出应该包含 CA:TRUE。如果没有,说明你生成证书时忘了加扩展属性,后面用它签发的子证书会不被浏览器或操作系统信任。
4.6 小结
到这步,你的根CA就搭好了。私钥在 private/ 里锁着,根证书在根目录下躺着,工作目录结构清晰,验证也通过了。说实话,这套流程我用了好几年,从实验室到生产环境都没出过岔子。
嗯,这里要再啰嗦一句:根CA的私钥最好离线存储。我在生产环境里会把私钥放到加密U盘里,只在需要签发中间CA时才挂载。平时服务器上只留根证书,不留私钥。这样就算服务器被攻破,攻击者也拿不到你的CA私钥。