4、OpenSSL工具链:安装、常用命令与配置文件解析
说实话,OpenSSL 这玩意儿,几乎是每个做安全的人绕不开的工具。我最早接触它的时候,还是在一个内部 CA 搭建项目里。那时候我天真地以为,装个 OpenSSL,跑几条命令,证书链就出来了。结果呢?折腾了一整天,生成的证书浏览器就是不认。后来才发现,是配置文件里一个参数写错了。
嗯,咱们这一章,就把 OpenSSL 的工具链彻底捋一遍。从安装开始,到常用命令,再到那个让人头疼的配置文件。你跟着我走一遍,以后碰到类似问题,心里就有底了。
4.1 安装 OpenSSL:不同平台的选择
OpenSSL 的安装其实不复杂,但不同系统有不同玩法。我个人习惯在 Linux 上搞,毕竟生产环境大多是 Linux。不过 Windows 和 macOS 也有对应的方案。
| 平台 | 安装方式 | 推荐版本 | 备注 |
|---|---|---|---|
| Ubuntu/Debian | sudo apt install openssl |
1.1.1 或 3.x | 系统源自带,省心 |
| CentOS/RHEL | sudo yum install openssl |
1.1.1k | 老版本可能需 EPEL 源 |
| macOS | brew install openssl |
3.x | Homebrew 安装后需手动链接 |
| Windows | 下载安装包或 WSL | 3.x | 建议用 WSL 体验更好 |
安装完后,验证一下版本:
openssl version
如果看到类似 OpenSSL 1.1.1k 25 Mar 2021 的输出,说明装好了。注意,版本号很重要。1.1.1 和 3.x 的某些命令行为略有差异,我后面会提到。
4.2 常用命令概览:你真正需要记住的
OpenSSL 的命令多到让人头皮发麻。但说实话,日常工作中,你真正需要记住的,不超过 10 条。我把它们分成了几类,这样好记。
4.2.1 密钥生成类
生成 RSA 私钥,这是最基础的操作:
openssl genrsa -out private.key 2048
2048 是密钥长度。我个人建议至少用 2048,别再用 1024 了,不安全。如果你想生成 ECC 密钥,用这个:
openssl ecparam -genkey -name prime256v1 -out ec_private.key
ECC 密钥更短,但安全性更高。我在移动端项目里常用它,因为性能好。
4.2.2 证书请求与签发
生成证书签名请求(CSR):
openssl req -new -key private.key -out request.csr
这条命令会问你一堆问题,比如国家、组织名、通用名(Common Name)。通用名一定要填对,它通常是域名或 IP。我曾经见过有人把通用名填成「测试证书」,结果浏览器直接报错。
自签名证书(用于测试):
openssl x509 -req -days 365 -in request.csr -signkey private.key -out certificate.crt
4.2.3 证书查看与转换
查看证书内容:
openssl x509 -in certificate.crt -text -noout
这个命令会输出证书的所有字段,包括颁发者、有效期、公钥信息等。调试时非常有用。
格式转换(比如从 PEM 转 DER):
openssl x509 -in cert.pem -outform DER -out cert.der
不同平台对证书格式要求不一样。Java 喜欢 DER,Nginx 喜欢 PEM。记住这条命令,省得临时抓瞎。
4.2.4 验证与调试
验证证书链:
openssl verify -CAfile ca.crt -untrusted intermediate.crt server.crt
这条命令会告诉你证书链是否完整。如果报错,多半是中间证书没配好。我在生产环境遇到过好几次,都是因为漏了中间证书。
genrsa— 生成 RSA 私钥req— 生成 CSR 或自签名证书x509— 证书查看、签名、转换verify— 验证证书链s_client— 测试 SSL/TLS 连接
4.3 配置文件解析:OpenSSL 的灵魂
很多人觉得 OpenSSL 难用,就是因为那个配置文件。说实话,我第一次看到 openssl.cnf 时,也是一脸懵。但后来我发现,只要搞懂几个关键段落,剩下的都是套路。
配置文件通常位于 /etc/ssl/openssl.cnf(Linux)或 /System/Library/OpenSSL/openssl.cnf(macOS)。你也可以自己指定:
openssl req -new -key private.key -out request.csr -config my_openssl.cnf
4.3.1 核心段落结构
配置文件主要分这几块:
- [ req ] — 请求相关的默认设置
- [ req_distinguished_name ] — 证书主题(Subject)的字段提示
- [ v3_req ] — 证书扩展(如 SAN)
- [ ca ] — CA 相关的默认设置
- [ policy_match ] — 策略匹配规则
举个例子,一个最简单的配置文件:
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = MyOrg
commonName = example.com
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = example.com
DNS.2 = www.example.com
看到没?prompt = no 表示不交互式提问,直接使用下面定义的值。这在自动化脚本里非常有用。我写 CI/CD 流水线时,都是这么干的。
4.3.2 最容易踩坑的地方:SAN(主题备用名称)
现在的浏览器,基本都要求证书里包含 SAN 字段。如果你只填了 Common Name,Chrome 会直接报错「NET::ERR_CERT_COMMON_NAME_INVALID」。
example.com,但 SAN 里忘了加。结果 Chrome 死活不认。后来查了半天才发现,是 subjectAltName 没配置。从那以后,我每次生成证书都会检查 SAN。
配置 SAN 的关键,就是在 [ v3_req ] 里加上 subjectAltName = @alt_names,然后在 [ alt_names ] 里列出所有域名或 IP。
4.3.3 策略匹配:CA 签名的规则
如果你在搭建 CA,[ policy_match ] 就很重要了。它定义了 CA 在签发证书时,必须匹配哪些字段。
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
match 表示必须和 CA 证书一致,supplied 表示必须提供,optional 表示可选。嗯,这里要注意,如果你把 countryName 设成 match,那所有子证书的国家必须和 CA 一样。我见过有人把 CA 的国家设成 US,子证书设成 CN,结果验证失败。
4.4 知识体系总览
为了让你更直观地理解 OpenSSL 工具链的组成,我画了一张图:
4.5 实战小技巧:让 OpenSSL 更好用
最后,分享几个我平时用的小技巧:
- 别名简化: 把常用命令写成 shell 别名,比如
alias certinfo='openssl x509 -text -noout -in',省得每次敲一长串。 - 批量生成: 用
for循环批量生成密钥和 CSR,适合测试环境。 - 日志调试: 加上
-debug参数,可以看到 OpenSSL 内部的处理过程,排查问题时很有用。
openssl.cnf 模板,每次生成证书时直接引用。这样团队里所有人都用同一套配置,不会出现「你生成的证书和我不一样」的尴尬情况。
好了,OpenSSL 工具链就讲到这里。你把这些命令和配置搞明白,后面搭建证书链就会顺畅很多。记住,配置文件是核心,别偷懒跳过它。