OpenSSL 常见问题
FreeGuideOnline
最新
2026-07-15
bash
PEM 转 DER(证书)
openssl x509 -in cert.pem -outform der -out cert.der
DER 转 PEM(证书)
openssl x509 -in cert.der -inform der -outform pem -out cert.pem
私钥转换同理,使用 rsa 或 ec 子命令
## 生成与检查密钥
### 如何生成 RSA 私钥?
```bash
# 生成 2048 位 RSA 私钥,并使用 AES256 加密保护
openssl genrsa -aes256 -out private.key 2048
# 生成无密码保护的私钥(不推荐)
openssl genrsa -out private.key 2048
生产环境推荐使用 2048 或 4096 位。若要去除已有私钥的密码:
openssl rsa -in encrypted.key -out decrypted.key
如何使用更现代的 ECDSA 密钥?
# 列出系统支持的椭圆曲线
openssl ecparam -list_curves
# 使用 prime256v1 (即 P-256) 生成私钥
openssl ecparam -genkey -name prime256v1 -out ecdsa.key
ECDSA 在同等安全强度下密钥更小、计算更快,推荐用于现代系统。
如何检查私钥信息?
# 查看私钥的算法、位数和公钥
openssl rsa -in private.key -text -noout
openssl ec -in ecdsa.key -text -noout
如果私钥有密码保护,会提示输入密码。
创建证书签名请求 (CSR) 与自签名证书
如何生成一个 CSR?
推荐使用配置文件方式(避免交互输入),或通过一条命令自动填写:
# 交互式生成 CSR(会询问国家、域名等)
openssl req -new -key private.key -out request.csr
# 一行命令非交互式生成(常用于脚本)
openssl req -new -key private.key -out request.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=www.example.com"
CN(Common Name)对于单域名证书就是完全合格的域名;使用 SAN(主题备用名)更加现代,见下一个问题。
如何生成带有 SAN 的 CSR?
自 Chrome 58 起,浏览器不再信任缺少 SAN 的 SSL 证书。你需要为 CSR 指定 SAN 扩展。首先创建一个配置文件 san.cnf:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[dn]
C=CN
ST=Beijing
L=Beijing
O=MyOrg
CN=www.example.com
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com
DNS.3 = *.example.com
然后执行:
openssl req -new -key private.key -out request.csr -config san.cnf
如何快速生成自签名证书?
自签名证书仅用于内部测试,浏览器会显示“不安全”。
# 生成有效期为 365 天的自签名证书(无 SAN)
openssl req -x509 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt -days 365 -nodes -subj "/CN=localhost"
# 生成带 SAN 的自签名证书(推荐),同样使用配置文件
openssl req -x509 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt -days 365 -nodes -config san.cnf -extensions req_ext
参数说明:
-x509表示直接输出证书而非 CSR。-nodes表示不加密私钥(no DES)。-days指定有效期。
证书查看与验证
如何查看证书的详细信息?
# 查看 PEM 格式证书的全部内容(包括有效期、颁发者、SAN)
openssl x509 -in certificate.crt -text -noout
# 查看证书的特定字段
openssl x509 -in certificate.crt -subject -issuer -dates -noout
如何从证书中提取公钥?
openssl x509 -in certificate.crt -pubkey -noout > pubkey.pem
如何验证证书是否匹配私钥?
比较公钥的哈希值:
# 私钥的公钥哈希
openssl rsa -in private.key -modulus -noout | openssl sha256
# 证书的公钥哈希
openssl x509 -in certificate.crt -modulus -noout | openssl sha256
若两个哈希完全相同,则密钥对匹配。
如何验证证书链是否完整?
# 验证由 CA 签发的证书,需要提供中间证书包
openssl verify -CAfile ca-bundle.crt certificate.crt
# 如果是自签名证书或信任锚
openssl verify -CAfile root-ca.crt -untrusted intermediate.crt server.crt
在日常部署中,如果中间证书缺失,浏览器可能无法构建信任链,报 SSL证书不受信任 错误。
格式转换与实用操作
如何将 CRT 和 KEY 合并为 PFX/PKCS#12?
Windows IIS 常用 PFX 格式,包含了证书和私钥。
# 将证书链(yourcert.crt + intermediates.crt)与私钥合并为 pfx
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in yourcert.crt -certfile ca-bundle.crt
如何从 PFX 中提取证书和私钥?
# 提取私钥(需输入原 PFX 密码,之后设置新密码或留空)
openssl pkcs12 -in certificate.pfx -nocerts -out private.key -nodes
# 提取所有证书(包括叶子证书和 CA)
openssl pkcs12 -in certificate.pfx -nokeys -out fullchain.crt
证书文件里包含多段 BEGIN/END ,如何拆分?
一个文件包含服务器证书、中间证书、根证书时,可以手动或使用命令拆分:
# 使用 awk 拆分第一个证书
awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' fullchain.pem | head -n $(( $(grep -c "CERTIFICATE" fullchain.pem)/2 )) > server.crt
更可靠的方法是使用工具 csplit 或 openssl 分行读取:
csplit -f cert- fullchain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'
然后删除空文件,按需重命名。
如何在不解密私钥的情况下移除密码?(其实就是“解密”)
openssl rsa -in encrypted.key -out decrypted.key
# ECDSA 私钥
openssl ec -in encrypted_ec.key -out decrypted_ec.key
注意这会生成一份无密码保护的私钥文件,权限应设置为 600。
连接与调试
如何使用 OpenSSL 测试远程服务器的 SSL/TLS 支持?
# 测试基本连接并显示证书链
openssl s_client -connect example.com:443 -showcerts
# 指定使用的 TLS 版本,如测试 TLS 1.2
openssl s_client -connect example.com:443 -tls1_2
# 使用 SNI 指定域名(某些服务器需要)
openssl s_client -connect 1.2.3.4:443 -servername example.com
如何检查证书是否即将过期?
# 获取远程证书过期时间
echo | openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | openssl x509 -noout -dates
# 本地证书过期时间
openssl x509 -in certificate.crt -noout -enddate
常见的 unable to get local issuer certificate 错误怎么解决?
该错误表示 OpenSSL 在验证链时找不到颁发者证书(中间 CA)。解决方式:
- 确保你拥有完整的中间证书(通常 CA 会提供 bundle)。
- 在命令中使用
-CAfile指向包含根证书和中间证书的 bundle 文件。 - 如果是自签名证书,需要在客户端信任该根证书。
杂项与批量处理
如何生成随机密码或随机数据?
# 生成 32 位随机十六进制字符串
openssl rand -hex 32
# 生成 base64 编码的 48 字节随机数
openssl rand -base64 48
如何批量转换某个目录下所有 CER 为 PEM?
for f in *.cer; do
openssl x509 -in "$f" -inform der -out "${f%.cer}.pem" -outform pem
done