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:下一个证书的序列号
注意:private 目录的权限一定要设为 700。私钥泄露了,你签的所有证书都不安全。我之前见过有人把私钥放在 755 的目录下,结果被扫描工具扒走了,整个 PKI 重建,教训深刻。

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 地址。

避坑指南:我曾经遇到一个项目,设备证书的 CN 用了中文,结果某款嵌入式设备解析失败。从那以后,我所有设备的 CN 只用英文、数字和连字符。

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 核心流程总览

我把整个流程画了张图,你一看就明白。

OpenSSL 证书签发流程 1. 安装 OpenSSL yum/apt 安装 + 目录准备 2. 生成 CA 根证书 生成私钥 → 自签名 3. 设备 CSR 密钥 + 请求 4. CA 签名 openssl ca 命令 5. 设备证书 .crt 文件 + 私钥 6. 部署到设备 证书 + 私钥 + CA 根证书 ⚠ 关键检查点 • 私钥权限 600/700 • CN 与设备标识一致 • 证书有效期合理

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 根证书和设备证书应该都能顺利签发出来。后面章节我们会聊证书的部署和轮换策略,那些才是生产环境里真正考验人的地方。