OpenSSL 深入解析
bash openssl version
若未安装,可使用包管理器进行安装:
```bash
# Ubuntu / Debian
sudo apt update && sudo apt install openssl
# CentOS / RHEL
sudo yum install openssl
Windows 用户可从 slproweb.com 下载安装包。
核心子命令结构
OpenSSL 采用 openssl <子命令> [选项] 的形式。最常用的子命令包括:
genrsa/genpkey– 生成 RSA 或通用私钥rsa– 处理 RSA 密钥req– 创建签名请求(CSR)和自签名证书x509– 管理 X.509 证书s_client– TLS/SSL 客户端连接测试enc– 对称加密与解密dgst– 生成消息摘要(哈希)
密钥管理:非对称加密的根基
生成 RSA 私钥
使用 genpkey 生成 2048 位 RSA 私钥(建议至少 2048 位,当前生产环境常用 4096 位):
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
加密私钥(设置密码保护):
openssl genpkey -algorithm RSA -aes256 -out private_encrypted.pem -pkeyopt rsa_keygen_bits:2048
传统的 genrsa 依然可用,但 genpkey 更通用,未来兼容性更好。
从私钥中提取公钥
openssl rsa -pubout -in private_key.pem -out public_key.pem
查看密钥内容
# 查看私钥的文本描述
openssl rsa -text -noout -in private_key.pem
# 查看公钥
openssl rsa -pubin -text -noout -in public_key.pem
转换私钥格式(PEM ↔ DER)
PEM 是 Base64 编码的文本格式,DER 是二进制格式。
# PEM 转 DER
openssl rsa -in private_key.pem -outform DER -out private_key.der
# DER 转 PEM
openssl rsa -in private_key.der -inform DER -out private_key.pem
证书与签名请求(CSR)
生成自签名证书
在测试或内网环境中,通常直接生成自签名证书。以下命令一步生成私钥和自签名证书:
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
-nodes:不加密私钥(No DE-S 去除 DES)。-x509:输出自签名证书而不是 CSR。-days:证书有效天数。
执行时会提示输入国家、省份、常用名称(CN)等信息,其中 Common Name 必须与服务器域名/IP 一致。
生成证书签名请求(CSR)
当需要由 CA 签发证书时,先生成 CSR:
openssl req -new -key private_key.pem -out request.csr
通过 -subj 参数可非交互式传递主题信息:
openssl req -new -key private_key.pem -out request.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=www.example.com"
使用自有 CA 签发证书
-
创建 CA 私钥和自签名 CA 证书
openssl req -newkey rsa:4096 -keyout ca.key -x509 -days 3650 -out ca.crt -subj "/CN=My Private CA" -
用 CA 签发用户证书
openssl x509 -req -in request.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out signed.crt -days 365-CAcreateserial会自动创建序列号文件,用于后续签发。
验证证书
查看证书详情:
openssl x509 -in server.crt -text -noout
验证证书链:
openssl verify -CAfile ca.crt signed.crt
检查私钥、证书和 CSR 是否匹配(模数一致):
openssl rsa -noout -modulus -in private_key.pem | openssl md5
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl req -noout -modulus -in request.csr | openssl md5
三个输出应完全相同。
对称加密与数据加密
OpenSSL 的 enc 命令支持 AES、DES、3DES、RC4 等多种算法。
使用密码加密文件
# 加密 (输出为 Base64)
openssl enc -aes-256-cbc -salt -in plain.txt -out encrypted.enc -pass pass:MyPassword
# 解密
openssl enc -d -aes-256-cbc -in encrypted.enc -out decrypted.txt -pass pass:MyPassword
-salt 增加密码强度,默认已开启。也可以使用密钥文件(-pass file:keyfile)代替明文密码。
直接基于密钥的加解密
生成随机密钥和向量:
openssl rand -out key.bin 32 # 256 位密钥
openssl rand -out iv.bin 16 # 128 位 IV
加密:
openssl enc -aes-256-cbc -in data.txt -out data.enc -K $(xxd -p key.bin) -iv $(xxd -p iv.bin)
解密时将 -K 和 -iv 代入相同值。
注意:-K 和 -iv 需要十六进制字符串,使用 xxd -p 转换二进制文件。
哈希与消息摘要
计算文件的 SHA256 哈希:
openssl dgst -sha256 file.txt
或直接使用独立的哈希命令:
openssl sha256 file.txt
生成 HMAC(带密钥的哈希):
openssl dgst -sha256 -hmac "secretkey" file.txt
SSL/TLS 连接诊断
openssl s_client 是一个强大的调试工具,可模拟 SSL 客户端连接。
查看服务器证书链和协商信息:
openssl s_client -connect www.example.com:443 -showcerts
指定 SNI(服务器名称指示),用于虚拟主机:
openssl s_client -connect 192.168.1.10:443 -servername www.example.com
测试特定 TLS 版本或密码套件:
# 仅使用 TLS 1.2
openssl s_client -connect example.com:443 -tls1_2
# 指定密码套件
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES128-GCM-SHA256'
检查证书过期时间(不建立完整连接):
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
格式转换:PEM、DER、PKCS#12
PKCS#12 生成与提取
PKCS#12(.pfx/.p12)文件常用于 Windows/IIS,将私钥和证书打包。
生成 PKCS#12 文件:
openssl pkcs12 -export -out bundle.pfx -inkey private_key.pem -in certificate.crt -certfile ca.crt
从 PKCS#12 提取私钥和证书:
# 提取私钥
openssl pkcs12 -in bundle.pfx -nocerts -nodes -out private.key
# 提取证书
openssl pkcs12 -in bundle.pfx -clcerts -nokeys -out cert.crt
实用技巧与常见场景
生成 Diffie-Hellman 参数
openssl dhparam -out dhparams.pem 2048
检查 OCSP 响应
openssl ocsp -issuer ca.crt -cert server.crt -url http://ocsp.example.com -text
创建自签名 SAN 证书(多域名)
新建 san.cnf 配置文件:
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = mydomain.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = mydomain.com
DNS.2 = www.mydomain.com
IP.1 = 192.168.1.100
生成证书:
openssl req -new -newkey rsa:2048 -nodes -keyout san.key -config san.cnf -x509 -days 365 -out san.crt