OpenSSL 快速入门——你的证书工具箱

说实话,做 mTLS 测试绕不开 OpenSSL。我最早接触它是在配置 HTTPS 证书的时候,敲了几条命令就把证书搞定了,当时觉得这工具真硬核。后来做接口测试,发现 OpenSSL 简直就是证书领域的瑞士军刀。这一章我带你快速上手,把最常用的几个命令吃透。

4.1 安装 OpenSSL

先把环境搭好。各平台安装方式不太一样,我列个表你对着来:

操作系统 安装方式 验证命令
Ubuntu / Debian sudo apt-get install openssl -y openssl version
CentOS / RHEL sudo yum install openssl -y openssl version
macOS brew install openssl openssl version
Windows 下载安装包或使用 WSL openssl version

我个人习惯在 Linux 环境下操作 OpenSSL,输出更干净,路径问题也少。Windows 用户建议直接用 WSL,省去配置环境变量的麻烦。

装完之后跑一句 openssl version,看到类似 OpenSSL 3.0.2 15 Mar 2022 的输出,就说明装好了。版本号最好在 1.1.1 以上,老版本有些命令参数不一样。

4.2 核心命令全景图

在敲命令之前,先看看这几个核心命令在整个证书生命周期里扮演什么角色。下面这张图我归纳了从生成私钥到验证证书的完整链条:

OpenSSL 核心命令与证书生命周期 OpenSSL 核心命令与证书生命周期 genrsa 生成 RSA 私钥 req 创建证书签名请求 x509 签发与格式转换 verify 验证证书链 查看证书信息 💡 使用 x509 -text 可查看证书全部字段

这套流程从左往右走:先拿 genrsa 生成私钥,然后用 req 创建证书请求,接着用 x509 完成签发或格式转换,最后用 verify 验证证书链对不对。而 x509 本身还能查看证书详情,我经常拿它来调试。

4.3 核心命令详解

四个命令各有分工,先看一张对比表,心里有个底:

命令 核心用途 常用参数 输出文件
genrsa 生成 RSA 私钥 -out、-aes256、2048 .pem / .key
req 创建 CSR 或自签名证书 -new、-x509、-key、-subj .csr / .pem
x509 证书签发、格式转换、查看 -text、-in、-signkey、-days .pem / .crt
verify 验证证书链有效性 -CAfile、-untrusted 无(仅输出校验结果)

genrsa —— 生成私钥

这是所有证书操作的起点。私钥丢了,后面全白搭。我习惯生成 2048 位的 RSA 私钥,够用且性能适中。

# 生成不加密的私钥
openssl genrsa -out server.key 2048

# 生成带密码保护的私钥
openssl genrsa -aes256 -out server-enc.key 2048

我曾经因为生成私钥时忘了加 -aes256,导致私钥文件明文存储在服务器上。后来被人扫到,差点出事。生产环境一定给私钥加上密码保护。

req —— 创建证书请求或自签名证书

这个命令两个用途:生成证书签名请求(CSR),或者直接自签名证书。做测试时我更喜欢后者,省去 CA 签发的步骤。

# 生成自签名证书(测试最常用)
openssl req -x509 -newkey rsa:2048 \
  -keyout server.key -out server.crt \
  -days 365 -nodes \
  -subj "/CN=localhost/O=mTLS Test/C=CN"

# 仅生成 CSR(正式流程用)
openssl req -new -key server.key \
  -out server.csr \
  -subj "/CN=localhost/O=mTLS Test/C=CN"

-subj 参数指定证书主体的信息,CN 是最关键的字段——客户端验证时就是拿它和域名做比对。做测试时我建议 CN 写 localhost 或者 127.0.0.1,省得后面校验出问题。

x509 —— 签发、转换与查看

x509 是我用得最多的命令。它可以拿私钥直接签发证书,也能在 DER 和 PEM 格式之间互相转换,还能查看证书内部字段。

# 用已有私钥签发证书
openssl x509 -req \
  -in server.csr -signkey server.key \
  -out server.crt -days 365

# 查看证书详细信息
openssl x509 -text -in server.crt -noout

# PEM 转 DER
openssl x509 -in server.crt -outform DER -out server.der

为什么说它灵活?你想想看,一个命令同时覆盖了签署、查看、转换三个场景,省掉多少来回倒腾的时间。

verify —— 验证证书链

证书签完之后,是不是真的可信?verify 就是干这个的。它检查证书的签名、有效期、以及是否由指定的 CA 签发。

# 验证自签名证书
openssl verify -CAfile ca.crt server.crt

# 验证包含中间 CA 的证书链
openssl verify -CAfile ca.crt -untrusted intermediate.crt server.crt

我建议每次签署完证书都跑一遍 verify。曾经有一次我配错了中间证书的顺序,服务端死活认不到客户端证书,最后用 verify 一查才发现是证书链拼接反了。

4.4 查看证书信息

拿到一个证书,怎么知道里面写了什么?最直接的方法就是 openssl x509 -text。它能输出证书里几乎所有的字段。

openssl x509 -text -in server.crt -noout

输出内容很长,但重点关注这几个字段:

  • Subject——证书持有者信息,对应创建时的 -subj。
  • Issuer——签发者信息,自签名证书的 Subject 和 Issuer 是一样的。
  • Validity——有效起止日期,过期了客户端会报错。
  • Public Key——公钥信息,确认算法和位数是否匹配。
  • Signature Algorithm——签名算法,比如 sha256WithRSAEncryption。

我在项目中排查过一起 TLS 握手失败的问题,最后发现是证书里的 CN 写成了 IP 地址但服务端没做兼容配置。用 x509 -text 一眼就看到 CN 字段有问题。说白了,证书就是一堆结构化数据,查看命令就是你的 X 光机。

4.5 避坑与建议

跟 OpenSSL 打交道久了,难免碰到一些奇奇怪怪的问题。我把自己踩过的坑总结一下,你遇到类似情况可以少走弯路。

  • 私钥权限——私钥文件不要暴露给无关人员。我习惯创建完就跑 chmod 600 server.key。
  • 证书格式混淆——PEM 是文本格式(-----BEGIN CERTIFICATE-----),DER 是二进制。大部分场景用 PEM,Java 生态偏爱 DER 或 PKCS12。
  • 证书链顺序——服务端证书在前,中间 CA 在后,根 CA 可以不配。顺序反了验证就挂。
  • 版本兼容——OpenSSL 1.0.x 和 3.x 有些参数不同,比如 -nodes 在新版里还能用,但老版不支持某些算法。装之前确认一下版本。

我曾经因为 OpenSSL 版本太老,导致生成的证书签名算法是 SHA1,被现代浏览器直接拦截。后来统一升级到 1.1.1 以上,强制用 SHA256 签名,才消停。做 mTLS 测试前,先确认你的 OpenSSL 版本至少是 1.1.1。