2. OpenSSL 实战:从安装到证书签发,再到格式转换

OpenSSL 这个工具,说它是 PKI 世界的瑞士军刀一点不过分。我做了这么多年安全工程,几乎每天都要跟它打交道。这一章咱们就把它掰开揉碎了讲清楚——怎么装、怎么配、怎么生成 CA 根证书、怎么签发服务端证书,最后再聊聊那些让人头疼的格式转换。

本章核心脉络:安装配置 → 自建根 CA → 签发服务端证书 → 格式互转。每一步我都会把坑指给你看。

OpenSSL 实战知识体系 OpenSSL 核心 安装与配置 生成根 CA 证书 签发服务端证书 格式转换 Linux / macOS Windows PEM / DER / PFX 💡 核心逻辑:自建 CA → 信任锚点 → 签发证书 → 格式适配不同场景 所有操作都围绕 openssl 命令行,不依赖任何图形界面

2.1 安装 OpenSSL

不同平台安装方式差别挺大。我个人的习惯是:能用包管理器就别自己编译,除非你有特殊需求。

操作系统 安装命令 备注
Ubuntu/Debian sudo apt install openssl 通常预装,版本较新
CentOS/RHEL sudo yum install openssl 1.1.1 或 3.x 视发行版
macOS brew install openssl 系统自带版本较老,建议用 brew
Windows 下载安装包或使用 WSL 推荐 Win64 OpenSSL 项目

我的建议:安装完后先跑 openssl version 确认版本。我遇到过好几次系统自带的是 0.9.8,那玩意儿太老了,很多新特性不支持。

2.2 配置 OpenSSL

OpenSSL 的配置文件默认在 /etc/ssl/openssl.cnf(Linux)或 /System/Library/OpenSSL/openssl.cnf(macOS)。说实话,默认配置够用,但做 CA 的时候我建议你单独搞一份。

我个人习惯的做法:

  1. 复制一份默认配置到工作目录
  2. 修改 [ CA_default ] 段,把 dir 指向你的工作目录
  3. 设置 default_days,根证书我一般设 3650 天(10 年),服务端证书设 365 天
# 复制配置
cp /etc/ssl/openssl.cnf ./myca.cnf

# 关键修改点
[ CA_default ]
dir             = ./ca               # CA 工作目录
certs           = $dir/certs         # 已签发证书
crl_dir         = $dir/crl           # 证书吊销列表
database        = $dir/index.txt     # 证书数据库
new_certs_dir   = $dir/newcerts      # 新证书存放处
certificate     = $dir/cacert.pem    # CA 证书
serial          = $dir/serial        # 序列号文件
private_key     = $dir/private/cakey.pem  # CA 私钥
default_days    = 365                # 默认有效期
default_md      = sha256             # 摘要算法

注意:index.txt 和 serial 文件需要手动创建。index.txt 可以空着,serial 里写 01 就行。我曾经忘了建 serial,折腾了半小时才反应过来。

2.3 生成 CA 根证书

根证书是整个信任链的起点。说白了,它就是那个「我信它,所以它签的证书我也信」的锚点。

步骤其实就两步:生成私钥 → 自签名证书。

# 1. 生成 CA 私钥(4096 位 RSA)
openssl genrsa -out ca.key 4096

# 2. 生成自签名根证书
openssl req -new -x509 -days 3650 \
  -key ca.key \
  -out ca.crt \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyLab/CN=MyLab Root CA"

这里有个细节:-x509 表示直接输出自签名证书,不需要 CSR 环节。根证书嘛,自己签自己。

关键参数说明:

  • genrsa -out ca.key 4096:生成 4096 位 RSA 私钥,位数越高越安全,但加解密也越慢
  • -days 3650:根证书有效期 10 年,别设太短,否则你得频繁更新信任锚点
  • -subj:证书主体信息,CN 字段最重要,客户端会校验这个

2.4 签发服务端证书

这才是日常工作中最频繁的操作。我每个月至少签发几十张服务端证书,流程早就刻在肌肉记忆里了。

流程分三步:

  1. 生成服务端私钥
  2. 生成证书签名请求(CSR)
  3. 用 CA 根证书签发
# 1. 生成服务端私钥
openssl genrsa -out server.key 2048

# 2. 生成 CSR
openssl req -new -key server.key \
  -out server.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyLab/CN=www.mylab.com"

# 3. 用 CA 签发证书(有效期 365 天)
openssl x509 -req -days 365 \
  -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt \
  -extensions server_cert

避坑指南:我曾经给一个 HTTPS 服务签证书,忘了加 -extensions server_cert,结果浏览器一直报「证书用途不正确」。后来查了半天才发现,服务端证书必须包含 Server Authentication 扩展(OID 1.3.6.1.5.5.7.3.1)。

如果你需要支持多域名或 IP,可以在配置文件中加 subjectAltName:

# 在 openssl.cnf 中追加
[ server_cert ]
basicConstraints       = CA:FALSE
nsCertType             = server
nsComment              = "Server Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = serverAuth
keyUsage               = digitalSignature, keyEncipherment
subjectAltName         = @alt_names

[ alt_names ]
DNS.1 = www.mylab.com
DNS.2 = api.mylab.com
IP.1  = 192.168.1.100

2.5 证书格式转换

格式转换这块,说实话,是初学者最容易懵的地方。PEM、DER、PFX……到底什么区别?

格式 特点 常见场景
PEM Base64 编码,可读,含头尾标记 Linux/Unix 服务、Nginx、Apache
DER 二进制编码,不可读 Java 环境、某些嵌入式设备
PFX/P12 PKCS#12 格式,可包含私钥+证书链 Windows、IIS、导入导出

转换命令其实就那么几条,我列出来你直接复制用:

# PEM → DER(证书)
openssl x509 -in server.crt -outform DER -out server.der

# DER → PEM(证书)
openssl x509 -in server.der -inform DER -out server.crt

# PEM → PFX(证书+私钥,需要密码)
openssl pkcs12 -export \
  -in server.crt \
  -inkey server.key \
  -out server.pfx \
  -passout pass:YourPassword

# PFX → PEM(提取证书和私钥)
openssl pkcs12 -in server.pfx -out server.pem -nodes
# 会提示输入 PFX 密码,-nodes 表示不加密私钥

重要提醒:PFX 文件包含私钥,传输时一定要加密。我见过有人把 PFX 明文放在 Git 仓库里,那基本等于把家门钥匙挂在门外。

2.6 验证证书

签完证书别急着用,先验证一下。我每次签完都会跑这条命令:

# 验证证书链
openssl verify -CAfile ca.crt server.crt

# 查看证书详情
openssl x509 -in server.crt -text -noout

verify 命令会检查签名、有效期、用途。如果输出 OK,那基本没问题。如果报错,别慌,看错误信息——大部分时候是证书链没配全或者 CN 不匹配。

我的经验:验证这一步千万别省。有一次我帮同事排查问题,他签的证书死活不生效,我一查——证书里的 CN 写的是 localhost,但实际域名是 api.example.com。这种低级错误,verify 一眼就能看出来。

2.7 本章小结

这一章我们走完了 OpenSSL 实战的完整链路:安装、配置、建 CA、签证书、转格式、做验证。说白了,这些操作就是 PKI 管理的「基本功」,后面所有自动化脚本都是基于这些命令封装的。

你想想看,如果手动签发一张证书需要 5 分钟,那 100 张就是 500 分钟。但如果你把这些命令写成脚本,100 张证书可能只需要 30 秒。这就是自动化的价值——不过那是后面章节的事了。