4、OpenSSL实战:安装、配置与根CA/中间CA证书生成
说实话,很多搞了几年证书的人,对OpenSSL还是「会用但不懂」。命令行敲得溜,但一问到配置文件里那几百行参数是干嘛的,就含糊了。
我个人习惯是:先把OpenSSL当成一个工具箱摸透,再谈企业级PKI。这一章,我们就从零开始,把OpenSSL装好、把配置文件读透、然后亲手生成一套根CA和中间CA。
本章核心目标:搭建一个可复用的两级CA体系,为后续的证书链故障诊断打下基础。
4.1 OpenSSL安装:别小看这一步
不同操作系统,安装方式略有差异。我建议你尽量用包管理器,别自己编译——除非你有特殊需求。
| 操作系统 | 安装命令 | 备注 |
|---|---|---|
| Ubuntu/Debian | sudo apt install openssl |
一般系统自带,版本可能偏旧 |
| CentOS/RHEL 7+ | sudo yum install openssl |
RHEL 8/9 用 dnf |
| macOS | brew install openssl |
系统自带的是LibreSSL,建议用Homebrew装OpenSSL |
| Windows | 下载安装包或WSL | 我个人不推荐Windows原生跑OpenSSL,坑多 |
小提示:装完后跑一下 openssl version,确认版本号。我建议用 1.1.1 以上版本,3.0 更好。1.0.2 已经EOL了,别用了。
4.2 配置文件解读:OpenSSL的「灵魂」
OpenSSL的配置文件默认在 /etc/ssl/openssl.cnf(Linux)或 /usr/local/etc/openssl@3/openssl.cnf(macOS)。
你想想看,这个文件定义了CA怎么干活:密钥放哪、证书有效期多久、扩展字段填什么。不读懂它,你生成的证书就是「野路子」。
4.2.1 核心段落结构
配置文件分几个大段,我用表格给你拆开:
| 段落名 | 作用 | 我常改的参数 |
|---|---|---|
[ req ] |
定义证书签名请求(CSR)的默认行为 | default_bits、distinguished_name |
[ ca ] |
定义CA操作(签名、吊销)的默认配置 | default_ca 指向哪个CA段 |
[ CA_default ] |
CA的具体工作目录、数据库、序列号文件 | dir、database、serial |
[ policy_match ] |
CA签名时对CSR字段的匹配策略 | 企业内一般用 policy_anything |
[ v3_ca ] |
CA证书的X.509 v3扩展 | basicConstraints、keyUsage |
[ v3_req ] |
终端证书的扩展 | subjectAltName 必须配 |
注意:默认配置里 [ policy_match ] 要求国家、组织名必须匹配。我在项目中遇到过,用默认配置给不同部门的服务器签名,结果一直报错。后来改成 policy_anything 才解决。
4.2.2 我常用的自定义配置片段
嗯,这里我直接贴一段我自己的模板,你拿去改改就能用:
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
prompt = no
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = MyCompany
organizationalUnitName = IT Security
commonName = MyCompany Root CA
[ v3_ca ]
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
注意 prompt = no,这样生成CSR时不会弹交互式问答,适合脚本化。我所有自动化流程都用这个。
4.3 生成根CA证书
根CA是信任链的锚点。它一旦泄露,整个PKI就完了。所以,根CA的私钥一定要保护好。
4.3.1 创建目录结构
我习惯这样组织文件:
mkdir -p ~/myCA/rootCA/{certs,crl,newcerts,private}
chmod 700 ~/myCA/rootCA/private
touch ~/myCA/rootCA/index.txt
echo 1000 > ~/myCA/rootCA/serial
certs:存放已签发的证书crl:证书吊销列表newcerts:OpenSSL自动生成的证书副本private:私钥目录,权限必须700index.txt:证书数据库,OpenSSL用它追踪已签证书serial:序列号计数器,从1000开始
4.3.2 生成根CA私钥和证书
先搞私钥,再搞证书。两步走:
# 第一步:生成RSA私钥,4096位,带AES-256加密
openssl genrsa -aes256 -out ~/myCA/rootCA/private/ca.key.pem 4096
# 第二步:生成自签名根证书,有效期20年
openssl req -config openssl.cnf \
-key ~/myCA/rootCA/private/ca.key.pem \
-new -x509 -days 7300 -sha256 \
-extensions v3_ca \
-out ~/myCA/rootCA/certs/ca.cert.pem
经验之谈:根CA有效期我一般设10-20年。太短了要频繁换根,太长了万一算法被破解也麻烦。20年是个折中。
验证一下证书内容:
openssl x509 -in ~/myCA/rootCA/certs/ca.cert.pem -text -noout
重点关注 Basic Constraints: CA:TRUE 和 Key Usage: Certificate Sign, CRL Sign。缺了这两个,它就不是一个合格的CA证书。
4.4 生成中间CA证书
根CA不能直接签终端证书。为什么?因为根CA私钥一旦用于日常签名,暴露风险太大。中间CA就是那个「干活的人」。
4.4.1 创建中间CA目录
mkdir -p ~/myCA/intermediateCA/{certs,crl,newcerts,private,csr}
chmod 700 ~/myCA/intermediateCA/private
touch ~/myCA/intermediateCA/index.txt
echo 1000 > ~/myCA/intermediateCA/serial
echo 1000 > ~/myCA/intermediateCA/crlnumber
4.4.2 生成中间CA私钥和CSR
# 私钥
openssl genrsa -aes256 \
-out ~/myCA/intermediateCA/private/intermediate.key.pem 4096
# CSR
openssl req -config intermediate_openssl.cnf \
-key ~/myCA/intermediateCA/private/intermediate.key.pem \
-new -sha256 \
-out ~/myCA/intermediateCA/csr/intermediate.csr.pem
注意这里用的是 intermediate_openssl.cnf,它和根CA的配置略有不同——basicConstraints 要设 CA:TRUE, pathlen:0,限制中间CA下面不能再有CA。
4.4.3 用根CA签名中间CA证书
这一步是关键。根CA给中间CA签名,形成信任链:
openssl ca -config root_openssl.cnf \
-extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-in ~/myCA/intermediateCA/csr/intermediate.csr.pem \
-out ~/myCA/intermediateCA/certs/intermediate.cert.pem
签名时,OpenSSL会检查CSR里的字段是否匹配策略。如果报错,八成是 policy 没配对。
我曾经遇到过一个问题:签名时提示「TXT_DB error number 2」。查了半天,原来是 index.txt 里已经有重复的序列号。清空 index.txt 重新来就好了。
4.5 验证证书链
证书生成完,必须验证链是否完整。命令很简单:
openssl verify -CAfile ~/myCA/rootCA/certs/ca.cert.pem \
~/myCA/intermediateCA/certs/intermediate.cert.pem
如果输出 intermediate.cert.pem: OK,说明链没问题。
如果报 unable to get local issuer certificate,说明根证书没找到或者中间证书的签发者不匹配。
4.6 本章知识体系图
下面这张SVG图,把根CA和中间CA的生成流程、文件关系画清楚了。建议你对照着操作:
4.7 避坑指南
最后,我把自己踩过的坑列一下,你遇到了直接对照:
- 私钥权限:
private/目录一定要chmod 700,私钥文件600。我曾经因为权限不对,导致自动化脚本读不到私钥,半夜被叫起来修。 - 序列号重复:如果
serial文件内容被重置或重复,签名会失败。每次签名前检查一下cat serial。 - index.txt 损坏:不要手动编辑
index.txt,格式错了OpenSSL就不认了。用openssl ca自带的命令操作。 - 证书扩展缺失:终端证书必须带
subjectAltName,否则浏览器会报错。CA证书必须带CA:TRUE。 - 路径长度限制:中间CA的
pathlen:0限制了它不能再签发下级CA。如果你需要多级CA,记得调整这个值。