4. OpenSSL 实战:生成自签名证书、查看证书内容、证书格式转换
说实话,很多运维干了好几年,天天跟 HTTPS 打交道,但真要他手搓一个自签名证书,可能还得翻半天文档。我当年刚入行时也这样——总觉得 OpenSSL 命令又长又绕,记不住。
但后来我发现,只要搞懂三个核心操作,证书这块基本就通了:生成、查看、转换。这节课,咱们就围绕这三件事,把 OpenSSL 玩明白。
4.1 生成自签名证书:从零到一
自签名证书,说白了就是自己给自己当 CA。测试环境、内网服务、开发调试,全靠它。我习惯把生成过程拆成两步:先搞出私钥,再拿私钥去签证书。
4.1.1 生成 RSA 私钥
私钥是证书的命根子。丢了私钥,证书就是一张废纸。我个人习惯用 2048 位,兼顾安全与性能。
# 生成 2048 位 RSA 私钥,保存为 server.key
openssl genrsa -out server.key 2048
命令跑完,你会得到一个 PEM 格式的文件。里面长这样:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...
-----END PRIVATE KEY-----
chmod 600 server.key
4.1.2 生成证书签名请求(CSR)
有了私钥,下一步是生成 CSR。CSR 相当于一张「申请表」,里面填了你的域名、公司、地区等信息。
openssl req -new -key server.key -out server.csr
执行后,OpenSSL 会交互式问你一堆问题。我直接给你一个非交互式的写法,省事:
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=Dev/CN=www.example.com"
这里 CN 是最关键的字段——Common Name,填你的域名或 IP。浏览器校验证书时,主要就看这个字段跟你访问的地址是否匹配。
4.1.3 自签名:给自己发证
拿着 CSR 和私钥,用下面这条命令给自己签发证书,有效期设 365 天:
openssl x509 -req -days 365 -in server.csr \
-signkey server.key -out server.crt
搞定。现在你有了三个文件:
server.key— 私钥,绝密server.csr— 请求文件,签名后可以删掉server.crt— 自签名证书,分发给客户端
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes参数
-nodes 表示不给私钥加密,省去输入密码的麻烦。测试环境用用可以,生产环境不建议。
4.2 查看证书内容:读懂里面的信息
证书生成完了,怎么确认里面写了啥?我见过不少同事直接 cat 文件看乱码,其实 OpenSSL 提供了专门的查看命令。
4.2.1 查看 PEM 格式证书
openssl x509 -in server.crt -text -noout
输出会包含:
- Subject — 证书持有者信息,就是你 CSR 里填的那些
- Issuer — 签发者信息。自签名证书的 Issuer 和 Subject 是一样的
- Validity — 有效期起止时间
- Public Key — 公钥算法和长度
- Signature Algorithm — 签名算法,比如 sha256WithRSAEncryption
我经常用这个命令来检查证书是不是快过期了:
openssl x509 -in server.crt -noout -dates
输出类似:
notBefore=Jan 1 00:00:00 2024 GMT
notAfter=Jan 1 00:00:00 2025 GMT
4.2.2 查看私钥信息
openssl rsa -in server.key -text -noout
可以查看私钥的模数、指数等细节。不过日常用得少,我一般只用来确认私钥文件是否损坏。
4.2.3 查看 CSR 内容
openssl req -in server.csr -text -noout
这个在提交 CSR 给 CA 之前检查一遍,能避免填错信息。我曾经就因为把 CN 写成了 IP 地址,导致证书签发后没法用——嗯,那次折腾了半小时。
4.3 证书格式转换:PEM / DER / PFX
不同平台、不同软件对证书格式的要求不一样。Nginx 喜欢 PEM,Java 喜欢 PFX,Windows 喜欢 DER。所以格式转换是运维的必修课。
| 格式 | 特点 | 常见后缀 | 典型用途 |
|---|---|---|---|
| PEM | Base64 编码,纯文本,可包含证书和私钥 | .pem, .crt, .key | Linux 服务器、Nginx、Apache |
| DER | 二进制编码,不可直接阅读 | .der, .cer | Windows 系统、Java 证书库 |
| PFX/P12 | PKCS#12 格式,可打包证书+私钥,有密码保护 | .pfx, .p12 | IIS、Windows 导入导出、Java KeyStore |
4.3.1 PEM ↔ DER 互转
PEM 转 DER:
openssl x509 -in server.crt -outform der -out server.der
DER 转 PEM:
openssl x509 -in server.der -inform der -out server.crt
你想想看,二进制转文本其实就是加了个 Base64 的头尾和换行。原理不复杂,但命令参数容易搞混。我每次都要在脑子里过一遍:-inform 指定输入格式,-outform 指定输出格式。
4.3.2 生成 PFX 文件
PFX 可以把证书和私钥打包成一个文件,方便迁移。生成时需要设置导出密码:
openssl pkcs12 -export -in server.crt -inkey server.key \
-out server.pfx -passout pass:YourPassword
参数说明:
-export— 执行导出操作-in— 输入证书文件-inkey— 输入私钥文件-passout pass:— 设置 PFX 的导出密码
4.3.3 从 PFX 中提取证书和私钥
反过来,从 PFX 里拆出 PEM 格式的证书和私钥:
# 提取证书
openssl pkcs12 -in server.pfx -nokeys -out cert.pem -passin pass:YourPassword
# 提取私钥
openssl pkcs12 -in server.pfx -nocerts -out key.pem -passin pass:YourPassword -passout pass:NewPassword
注意:提取私钥时,OpenSSL 会要求你再设一个密码来保护私钥文件。如果不想设,加个 -nodes 参数:
openssl pkcs12 -in server.pfx -nocerts -out key.pem -nodes -passin pass:YourPassword
4.4 本章知识体系
下面这张图,把 OpenSSL 的核心操作串起来了。你跟着箭头走一遍,就能理解证书从生成到转换的完整链路。
4.5 避坑指南
最后,分享几个我实战中遇到的坑,你碰到了能少走弯路:
- 证书和私钥不匹配:有时候证书过期了,你换了个新证书,但忘了换私钥。用
openssl x509 -noout -modulus -in server.crt | openssl md5和openssl rsa -noout -modulus -in server.key | openssl md5对比两个 MD5 值,一致才说明是配对。 - PFX 导入密码错误:Windows 导入 PFX 时,如果密码包含特殊字符,容易输错。我建议密码只用大小写字母+数字,别搞花里胡哨的符号。
- DER 文件打不开:DER 是二进制,别用 cat 或 vim 看。用
openssl x509 -in cert.der -inform der -text -noout查看。 - 证书链不完整:自签名证书没有中间 CA,但如果你后面用到 CA 签发的证书,记得把中间证书和服务器证书合并成一个 PEM 文件,否则 Nginx 会报错。
嗯,OpenSSL 这块内容不少,但核心就是生成、查看、转换三板斧。你把这节课的命令都敲一遍,以后遇到证书相关的问题,心里就有底了。