2. OpenSSL 实战:从安装到签发中间CA
说实话,OpenSSL 这个工具,又爱又恨。爱的是它免费、强大,几乎包办了所有证书操作;恨的是它的命令行参数设计得……嗯,有点反人类。我刚开始接触时,经常因为一个参数顺序不对,折腾半天。
但不管怎样,它是我们做证书生命周期自动化的基石。这一章,我们就把它彻底搞明白。
2.1 安装与基础配置
不同系统安装方式略有差异,但核心都一样。我个人习惯在 Linux 环境下操作,生产环境也建议如此。
| 操作系统 | 安装命令 | 备注 |
|---|---|---|
| Ubuntu/Debian | apt install openssl -y |
版本通常较新 |
| CentOS/RHEL 7/8 | yum install openssl -y |
RHEL 8 默认自带 1.1.1 |
| CentOS/RHEL 9+ | dnf install openssl -y |
默认 OpenSSL 3.x |
| macOS | brew install openssl |
系统自带版本较老,建议 brew |
openssl version。我遇到过因为系统自带 1.0.2 版本,导致 TLS 1.3 握手失败的坑。建议至少 1.1.1 以上。
安装完,我们需要一个干净的目录结构。这是我的习惯做法:
mkdir -p ~/pki/{ca,intermediate,server,client,private,crl}
chmod 700 ~/pki/private
touch ~/pki/index.txt
echo 1000 > ~/pki/serial
为什么这么搞?index.txt 是 OpenSSL 的证书数据库,记录所有已签发证书的状态。serial 文件记录下一个证书的序列号。这两个文件,是后面所有自动化操作的基础。
2.2 生成自签名根 CA
根 CA 是整个信任链的起点。说白了,它就是「我是我」的证明。生成根 CA 私钥和证书,我建议用以下参数:
# 1. 生成根 CA 私钥(4096位,更安全)
openssl genrsa -out ~/pki/private/ca.key.pem 4096
# 2. 生成根 CA 证书(自签名,有效期10年)
openssl req -x509 -new -nodes \
-key ~/pki/private/ca.key.pem \
-sha256 -days 3650 \
-out ~/pki/ca/ca.cert.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=My Root CA"
这里有个细节:-nodes 参数表示不对私钥加密。为什么?因为自动化脚本里每次输入密码不现实。但如果你手动操作,可以去掉 -nodes,OpenSSL 会提示你输入密码。
2.3 签发中间 CA 证书
根 CA 一般不直接签发服务器证书,而是签发中间 CA。这样做的好处是:即使中间 CA 私钥泄露,我们只需要吊销它,根 CA 仍然安全。
流程分三步:
- 生成中间 CA 私钥和证书签名请求(CSR)
- 用根 CA 签发中间 CA 证书
- 验证证书链
先看第一步:
# 生成中间 CA 私钥
openssl genrsa -out ~/pki/private/intermediate.key.pem 4096
# 生成中间 CA 的 CSR
openssl req -new -sha256 \
-key ~/pki/private/intermediate.key.pem \
-out ~/pki/intermediate/intermediate.csr \
-subj "/C=CN/ST=Beijing/O=MyOrg/CN=My Intermediate CA"
第二步,用根 CA 签发。这里需要创建一个扩展配置文件,指定中间 CA 的用途:
cat > ~/pki/intermediate/openssl_intermediate.cnf <<EOF
[v3_intermediate_ca]
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
EOF
openssl x509 -req -in ~/pki/intermediate/intermediate.csr \
-CA ~/pki/ca/ca.cert.pem \
-CAkey ~/pki/private/ca.key.pem \
-CAcreateserial \
-out ~/pki/intermediate/intermediate.cert.pem \
-days 1825 -sha256 \
-extfile ~/pki/intermediate/openssl_intermediate.cnf \
-extensions v3_intermediate_ca
pathlen:0 表示这个中间 CA 不能再签发下级 CA。如果你需要多级 CA 链,可以设置 pathlen:1 或更大。但生产环境建议 pathlen:0,减少攻击面。
第三步,验证证书链:
openssl verify -CAfile ~/pki/ca/ca.cert.pem \
~/pki/intermediate/intermediate.cert.pem
如果输出 intermediate.cert.pem: OK,说明签发成功。
2.4 核心命令行操作
除了签发证书,OpenSSL 还有很多实用操作。我挑几个高频场景:
| 操作 | 命令示例 | 说明 |
|---|---|---|
| 查看证书 | openssl x509 -in cert.pem -text -noout |
查看证书所有字段 |
| 查看 CSR | openssl req -in req.csr -text -noout |
确认 CSR 内容是否正确 |
| 转换格式 | openssl x509 -in cert.pem -outform der -out cert.der |
PEM 转 DER |
| 提取公钥 | openssl x509 -in cert.pem -pubkey -noout |
获取证书中的公钥 |
| 计算指纹 | openssl x509 -in cert.pem -fingerprint -sha256 |
用于校验证书一致性 |
举个例子,有一次我排查一个 TLS 握手失败问题,发现服务器证书和私钥不匹配。用以下命令快速定位:
# 比较证书公钥和私钥的模数
openssl x509 -in cert.pem -modulus -noout | openssl md5
openssl rsa -in key.pem -modulus -noout | openssl md5
如果两个 MD5 值一致,说明匹配。否则,就是证书和私钥对不上。
2.5 本章知识体系
下面这张图,概括了本章的核心流程和关系:
从图中可以看到,根 CA 是信任锚点,中间 CA 是桥梁,服务器和客户端证书是最终使用者。这个层级结构,就是 PKI 的核心思想。
2.6 避坑指南
最后,分享几个我踩过的坑:
- 序列号重复: 如果
serial文件没有正确递增,会导致证书序列号冲突。我曾经因为这个,导致一批证书在浏览器里被判定为重复,全部重新签发。建议用openssl x509 -serial -noout定期检查。 - 时间不同步: 签发证书时,系统时间必须准确。有一次我测试环境时间差了 5 分钟,证书「提前生效」,结果客户端验证失败。NTP 同步是必须的。
- 扩展属性遗漏: 签发服务器证书时,必须包含
subjectAltName(SAN)。否则 Chrome 会报错。我见过太多人只填了CN,忘了 SAN。
openssl x509 -in cert.pem -text -noout | grep -A 1 "Subject Alternative Name" 检查 SAN 字段。确保万无一失。
好了,这一章的内容就到这里。OpenSSL 的命令行操作,说白了就是「私钥生成 → CSR → 签发 → 验证」这个循环。把这个循环练熟了,后面的自动化脚本就是水到渠成的事。