3. OpenSSL 实战:安装配置、生成 CA 根证书、签发设备证书
说实话,很多运维兄弟一提到 OpenSSL 就头大。命令行参数又多又长,报错信息还经常看不懂。但你要做 PKI,这关必须过。我这些年折腾下来,发现只要把流程理清楚,OpenSSL 其实挺顺手的。
这一章,咱们就动手把 CA 根证书建起来,再签一张设备证书出来。你跟着我走一遍,以后自己搞证书心里就有底了。
3.1 OpenSSL 安装与基础配置
先看看你的环境。我习惯在 Linux 上搞,CentOS 和 Ubuntu 都行。
3.1.1 安装 OpenSSL
不同系统命令不一样,别搞混了。
| 操作系统 | 安装命令 | 验证版本 |
|---|---|---|
| CentOS / RHEL 7+ | yum install -y openssl |
openssl version |
| CentOS / RHEL 8+ | dnf install -y openssl |
openssl version |
| Ubuntu / Debian | apt-get install -y openssl |
openssl version |
openssl version -a,看看编译参数里有没有 enable-ec。没有的话,后面做 ECC 证书会报错。我曾经在一台旧机器上踩过这个坑,折腾了半天才发现是编译选项的问题。
3.1.2 准备目录结构
做 PKI 最怕文件乱放。我建议你从一开始就建好目录,后面省心很多。
mkdir -p ~/pki/ca
mkdir -p ~/pki/ca/private
mkdir -p ~/pki/ca/certs
mkdir -p ~/pki/ca/newcerts
mkdir -p ~/pki/ca/crl
touch ~/pki/ca/index.txt
echo 1000 > ~/pki/ca/serial
解释一下这些目录的用途:
- private/:放 CA 私钥,权限必须锁死
- certs/:放签发的证书文件
- newcerts/:OpenSSL 自动生成的证书副本
- crl/:证书吊销列表存放处
- index.txt:证书数据库,OpenSSL 用它记录每张证书的状态
- serial:下一个证书的序列号
3.2 生成 CA 根证书
根证书是整个信任链的起点。说白了,它就是“我是我,我信我”的那张证。
3.2.1 生成 CA 私钥
我建议用 ECC 算法,性能好,密钥短。当然 RSA 也完全没问题,看你的场景。
# 生成 ECC 私钥(推荐)
openssl ecparam -genkey -name prime256v1 -out ~/pki/ca/private/ca.key
# 或者生成 RSA 私钥(兼容性更好)
openssl genrsa -aes256 -out ~/pki/ca/private/ca.key 4096
这里有个细节:RSA 我加了 -aes256,意思是私钥用密码加密。每次用私钥都要输密码,安全但麻烦。ECC 默认不加密,你要想加密可以自己加参数。
选 RSA 还是 ECC?
- 设备性能弱(比如 IoT 模块)→ 用 ECC,计算量小
- 要兼容老系统(比如 Windows XP)→ 用 RSA
- 我自己的经验:新项目一律 ECC,省带宽省算力
3.2.2 自签 CA 根证书
私钥有了,接下来给自己发证。这个过程叫“自签名”。
openssl req -new -x509 -days 3650 \
-key ~/pki/ca/private/ca.key \
-out ~/pki/ca/certs/ca.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=PKI/CN=MyCompany Root CA"
参数说明:
- -x509:直接输出证书,不走 CSR 流程
- -days 3650:有效期 10 年。根证书一般签长一点,省得频繁换
- -subj:证书主体信息。CN 字段最重要,客户端会校验这个
嗯,这里要注意:根证书的 CN 不要随便写。我见过有人写 "Root CA",结果后面做双向认证时,设备端校验 CN 失败,排查了半天才发现是 CN 不匹配。
3.3 签发设备证书
根证书是“信任锚点”,设备证书才是真正给设备用的。流程分三步:生成设备密钥 → 生成证书签名请求(CSR)→ CA 签名。
3.3.1 生成设备密钥和 CSR
假设要给一台 IoT 网关发证书,设备 ID 是 gateway-001。
# 生成设备私钥
openssl ecparam -genkey -name prime256v1 -out ~/pki/ca/private/gateway-001.key
# 生成 CSR
openssl req -new \
-key ~/pki/ca/private/gateway-001.key \
-out ~/pki/ca/certs/gateway-001.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IoT/CN=gateway-001.mycompany.com"
CSR 里最关键的是 CN。设备证书的 CN 通常是设备的 FQDN 或者设备唯一标识。你要是做 IoT,CN 可以用设备序列号或者 MAC 地址。
3.3.2 配置 CA 签名策略
直接签名也能用,但不好管理。我建议写一个配置文件,把签名策略定下来。
创建 ~/pki/ca/openssl.cnf:
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ~/pki/ca
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
private_key = $dir/private/ca.key
certificate = $dir/certs/ca.crt
default_md = sha256
policy = policy_loose
copy_extensions = copy
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
这个配置的核心是 policy_loose。它只要求 CN 必须提供,其他字段可选。这样你签设备证书时灵活很多,不用每次都填一堆信息。
3.3.3 用 CA 签名设备证书
配置写好了,开始签名:
openssl ca -config ~/pki/ca/openssl.cnf \
-in ~/pki/ca/certs/gateway-001.csr \
-out ~/pki/ca/certs/gateway-001.crt \
-days 365 \
-notext \
-batch
参数解释:
- -config:指定我们刚写的配置文件
- -days 365:设备证书有效期 1 年。别签太长,方便轮换
- -batch:非交互模式,不弹确认框。脚本化部署时必备
签名完成后,检查一下证书:
openssl x509 -in ~/pki/ca/certs/gateway-001.crt -text -noout
看输出里的 Issuer 是不是你的 CA 的 CN,Subject 是不是设备的 CN。再确认一下 Validity 时间对不对。
3.4 核心流程总览
我把整个流程画了张图,你一看就明白。
3.5 常见问题与避坑
做多了你就会发现,OpenSSL 报错就那么几种。我列几个高频问题:
| 问题现象 | 原因 | 解决办法 |
|---|---|---|
unable to load private key |
私钥路径不对或权限不足 | 检查路径,确认私钥文件权限为 600 |
failed to update database |
index.txt 或 serial 文件缺失 | 重新 touch index.txt,echo 1000 > serial |
signature algorithm not supported |
OpenSSL 版本太老,不支持 sha256 | 升级 OpenSSL 或改用 sha1(不推荐) |
certificate is not trusted |
设备没安装 CA 根证书 | 把 ca.crt 导入设备信任存储 |
好了,这一章的内容就到这儿。你跟着步骤走一遍,CA 根证书和设备证书应该都能顺利签发出来。后面章节我们会聊证书的部署和轮换策略,那些才是生产环境里真正考验人的地方。