OpenSSL 深入解析

FreeGuideOnline 最新 2026-07-15

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 签发证书

  1. 创建 CA 私钥和自签名 CA 证书

    openssl req -newkey rsa:4096 -keyout ca.key -x509 -days 3650 -out ca.crt -subj "/CN=My Private CA"
    
  2. 用 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