3、OpenSSL工具实战:OpenSSL安装与配置、生成自签名证书、查看证书内容、证书格式转换
说实话,搞TLS证书管理,OpenSSL是绕不过去的工具。我入行那会儿,第一次配HTTPS就是被OpenSSL折腾得够呛——命令记不住,参数搞混,生成的证书浏览器还不认。后来摸爬滚打多了,才慢慢摸清它的脾气。
这一章,咱们就把它彻底吃透。从安装配置,到生成自签名证书,再到查看证书内容、做格式转换。全是实战干货,你跟着敲一遍,基本就上手了。
3.1 OpenSSL的安装与基础配置
OpenSSL几乎成了操作系统的标配。Linux发行版基本都自带,macOS也预装了。但版本差异挺大,我建议你先确认一下版本。
# 查看OpenSSL版本
openssl version
# 输出示例
OpenSSL 1.1.1k 25 Mar 2021
版本号很重要。1.1.1系列支持TLS 1.3,3.0系列开始引入全新许可证和架构。我个人习惯用1.1.1以上的版本,太老的版本有些新特性不支持。
各平台安装方式
| 操作系统 | 安装命令 | 备注 |
|---|---|---|
| Ubuntu/Debian | sudo apt install openssl |
通常已预装 |
| CentOS/RHEL | sudo yum install openssl |
或 dnf |
| macOS | brew install openssl |
系统自带版本较旧 |
| Windows | 下载安装包或WSL | 推荐用WSL |
配置文件在哪?
OpenSSL的行为很大程度上由配置文件控制。默认路径是 /etc/ssl/openssl.cnf(Linux)或 /System/Library/OpenSSL/openssl.cnf(macOS)。你可以通过 -config 参数指定自定义配置。
# 查看当前使用的配置文件
openssl version -d
# 输出示例
OPENSSLDIR: "/usr/lib/ssl"
嗯,这里要注意:配置文件里定义了CA路径、默认哈希算法、证书策略等。生成自签名证书时,如果没指定配置文件,有些字段会留空或取默认值。
3.2 生成自签名证书
自签名证书,说白了就是自己给自己当CA签发的证书。开发环境、内网测试用得最多。生产环境别这么干,浏览器会报不安全。
生成自签名证书分两步:先创建私钥,再基于私钥生成证书。我习惯一步到位:
# 生成私钥 + 自签名证书(一步完成)
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes
# 参数说明
# -x509 输出自签名证书,而不是证书签名请求
# -newkey 同时生成新私钥
# rsa:2048 RSA 2048位密钥
# -keyout 私钥输出文件
# -out 证书输出文件
# -days 365 有效期365天
# -nodes 私钥不加密(no DES)
执行后会让你填一堆信息:国家、省份、城市、组织名、通用名(Common Name, CN)。CN字段最关键,必须填你的域名或IP。我见过有人填了"localhost"结果部署到线上域名不匹配,证书直接废了。
example.com,CN就填 example.com。否则浏览器会提示证书名称不匹配。
分步生成(更灵活)
有时候你想先保存私钥,再慢慢生成证书。那就分两步走:
# 第一步:生成私钥
openssl genrsa -out server.key 2048
# 第二步:生成证书签名请求(CSR)
openssl req -new -key server.key -out server.csr
# 第三步:自签名(用私钥签署CSR)
openssl x509 -req -in server.csr -signkey server.key -out server.crt -days 365
分步的好处是,你可以把CSR发给真正的CA去签名,而不是自签名。我在项目中经常这么干——先用自签名证书做联调,等CA证书下来再替换。
指定Subject Alternative Names(SAN)
现代浏览器已经不看CN了,只看SAN。如果你的证书要支持多个域名或IP,必须加SAN。我当初升级一个老项目时就吃过这个亏——Chrome突然不认CN了,排查了半天。
# 创建配置文件 extra.cnf
cat > extra.cnf << EOF
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
IP.1 = 192.168.1.100
EOF
# 生成带SAN的自签名证书
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt \
-days 365 -nodes -extensions v3_req -config extra.cnf
3.3 查看证书内容
证书生成好了,怎么确认里面的信息对不对?用 openssl x509 命令查看。
# 查看证书内容(文本格式)
openssl x509 -in server.crt -text -noout
# 只看证书有效期
openssl x509 -in server.crt -dates -noout
# 只看主题信息
openssl x509 -in server.crt -subject -noout
# 查看证书指纹(用于校验)
openssl x509 -in server.crt -fingerprint -sha256 -noout
-text 输出最详细,包括版本、序列号、签名算法、颁发者、有效期、公钥信息、扩展项等。我经常用这个命令来快速验证证书是不是我生成的那张。
查看私钥信息
# 查看私钥的详细信息
openssl rsa -in server.key -text -noout
# 验证私钥与证书是否匹配
openssl rsa -in server.key -pubout -outform pem | openssl sha256
openssl x509 -in server.crt -pubkey -noout -outform pem | openssl sha256
# 对比两个哈希值,一致则匹配
你想想看,如果私钥和证书不匹配,部署上去HTTPS直接挂掉。我建议每次生成证书后都做一次这个校验,养成习惯。
3.4 证书格式转换
不同平台、不同软件对证书格式的要求不一样。Nginx喜欢PEM,Tomcat要JKS,Windows要PFX。OpenSSL就是格式转换的瑞士军刀。
| 格式 | 常见扩展名 | 特点 | 典型用途 |
|---|---|---|---|
| PEM | .pem, .crt, .key | Base64编码,可包含证书和私钥 | Nginx, Apache, Linux |
| DER | .der, .cer | 二进制编码 | Java, Windows |
| PKCS#12 | .p12, .pfx | 包含证书链和私钥,有密码保护 | IIS, Tomcat, Windows |
| JKS | .jks | Java专用密钥库 | Tomcat, Jetty |
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
PEM 转 PKCS#12(PFX)
# 将证书和私钥打包成PFX
openssl pkcs12 -export -in server.crt -inkey server.key \
-out server.p12 -name "My Server Cert" -password pass:changeit
# 参数说明
# -export 导出PKCS#12
# -inkey 指定私钥文件
# -name 证书别名(Java中常用)
# -password 设置PFX密码
PKCS#12 转 PEM
# 从PFX中提取证书和私钥
openssl pkcs12 -in server.p12 -out server.pem -nodes -password pass:changeit
# 如果只想提取证书
openssl pkcs12 -in server.p12 -out server.crt -nokeys -password pass:changeit
# 如果只想提取私钥
openssl pkcs12 -in server.p12 -out server.key -nocerts -nodes -password pass:changeit
3.5 本章知识体系
下面这张图把OpenSSL的核心操作串起来了,你可以对照着梳理一下思路。
说白了,OpenSSL就是一套命令行工具箱。安装好之后,私钥、证书、查看、转换,四个操作来回用。你只要把这一章的命令敲熟了,日常的证书管理基本够用了。
我记得刚带团队时,有个同事把PEM和DER搞混了,证书部署上去Nginx死活不认。我过去一看,文件头不对,直接一行命令转回来就好了。这种坑踩过一次,你就记住了。