openSSL介绍

openSSL介绍
安安OpenSSL 深度实战指南
1. 核心概念与文件后缀
在使用命令之前,必须理解 OpenSSL 操作的对象是什么。
| 后缀 | 全称 | 含义 | 内容 |
|---|---|---|---|
| .key | Private Key | 私钥 | 包含私有密钥信息,绝密,用于解密或签名。 |
| .csr | Certificate Signing Request | 证书签名请求 | 包含公钥和身份信息(CN, O 等),发送给 CA 进行签名。 |
| .crt / .pem | Certificate | 证书 | 包含公钥、身份信息、CA 的签名、有效期等。通常是 PEM 编码。 |
| .der | Distinguished Encoding Rules | 二进制证书 | 证书的二进制格式,无法直接用文本编辑器查看。 |
| .pfx / .pkcs12 | PKCS#12 | 证书包 | 包含证书链和私钥的加密打包文件,常用于 Windows/IIS/Java。 |
| .cnf / .conf | Configuration | 配置文件 | 定义 OpenSSL 行为、扩展属性(如 SAN)的文件。 |
注意:
.pem是一种编码格式(Base64 文本),.crt和.key文件内部通常也是 PEM 格式。可以用文本编辑器打开查看-----BEGIN...头尾。
2. 核心命令详解
OpenSSL 命令繁多,但证书管理主要围绕以下 4 个核心命令。
2.1 genrsa - 生成私钥
用于生成 RSA 算法的私钥。
1 | openssl genrsa -out server.key 2048 |
-out: 输出文件路径。2048: 密钥长度。建议最低 2048,生产环境推荐 4096。进阶: 生成 ECC 密钥(性能更好,证书更短):
1
openssl ecparam -genkey -name prime256v1 -out server.key
2.2 req - 管理证书请求 (CSR) 和自签名证书
这是最常用的命令,既能生成 CSR,也能直接生成自签名证书(CA)。
场景 A:生成 CSR (用于发给 CA 签名)
1 | openssl req -new -key server.key -out server.csr -subj "/CN=example.com" |
-new: 生成一个新的证书请求。-key: 指定已有的私钥。-subj: 直接指定主题信息,避免交互式输入。
场景 B:生成自签名证书 (常用于 CA 或测试)
1 | openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt |
-x509: 关键参数。输出自签名证书,而不是 CSR。-nodes: No DES。私钥不加密保护。如果去掉此参数,生成私钥时会要求输入密码,每次使用私钥都需要密码。-days: 证书有效期。
2.3 x509 - 证书操作与签名
用于查看证书内容,或作为 CA 签署 CSR。
场景:CA 签署服务器证书
1 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 |
-req: 输入是一个 CSR 文件。-CA/-CAkey: 指定颁发者(CA)的证书和私钥。-CAcreateserial: 自动创建序列号文件 (ca.srl),每次签名序列号递增。-extfile: (重要) 指定扩展配置文件,用于添加 SAN 等信息。
2.4 verify - 验证证书链
用于检查证书是否合法,是否由受信任的 CA 签署。
1 | # 验证 server.crt 是否由 ca.crt 签署 |
- 输出
OK表示验证通过。 - 如果证书链中间有缺失,可以使用
-untrusted参数加载中间证书。
3. 关键参数深度解析
理解参数背后的含义比死记硬背更重要。
3.1 -subj (主题信息)
格式为 /类型=值/类型=值。常见字段:
CN(Common Name): 通用名称。旧版 TLS 依赖它验证域名,新版依赖 SAN。O(Organization): 组织名称。OU(Organizational Unit): 部门。C(Country): 国家代码 (如 CN, US)。ST(State): 省份。L(Locality): 城市。
示例: "/C=CN/ST=Beijing/L=Beijing/O=MyCorp/CN=api.example.com"
3.2 -nodes (私钥加密)
- 含义: 生成的私钥文件不使用密码加密。
- 生产建议: 生产环境私钥应该加密(去掉
-nodes),但这样会导致服务重启时需要人工输入密码,不利于自动化。通常做法是:生成时加密,部署到服务器后移除密码保护,并通过文件系统权限 (chmod 600) 保护私钥。
3.3 -sha256 (签名算法)
- 含义: 使用 SHA-256 哈希算法进行签名。
- 注意: 绝对不要使用
md5或sha1,它们已被认为不安全,现代浏览器和客户端会拒绝信任。
3.4 扩展属性 (Extensions)
这是最容易出错的地方。证书不仅仅是公钥 + 身份,还包含用途限制。
- basicConstraints: 标识是否为 CA 证书 (
CA:TRUE或CA:FALSE)。 - keyUsage: 密钥用途 (如
digitalSignature,keyEncipherment)。 - extendedKeyUsage (EKU): 扩展用途。
serverAuth: 只能用于服务器端 (TLS Web Server Authentication)。clientAuth: 只能用于客户端 (TLS Web Client Authentication)。- 错误后果: 如果用服务器证书去做客户端认证,握手会失败 (
tls: internal error)。
4. SAN (Subject Alternative Name) 专题
为什么重要?
从 Go 1.15、Chrome 58 开始,不再信任 CN 字段,只信任 SAN 字段。如果证书没有 SAN,客户端会报错 x509: certificate relies on legacy Common Name field。
方法一:命令行直接添加 (OpenSSL 1.1.1+)
适合快速测试。
1 | openssl req -new -key server.key -out server.csr \ |
DNS:后面跟域名。IP:后面跟 IP 地址。
方法二:使用配置文件 (兼容所有版本,推荐生产)
创建一个 ext.cnf 文件:
1 | [ req ] |
生成 CSR 时使用:
1 | openssl req -new -key server.key -out server.csr -config ext.cnf |
签署证书时使用:
1 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ |
5. 证书查验与调试 (Inspect & Debug)
当证书出现问题时,不要猜,用 OpenSSL 查看。
5.1 查看证书详细信息
1 | openssl x509 -in server.crt -text -noout |
-text: 以文本形式打印详细信息。-noout: 不输出编码后的证书本身。- 重点关注:
Validity: 检查Not Before和Not After是否过期。Subject: 检查 CN。X509v3 Subject Alternative Name: 检查是否有 SAN。X509v3 Extended Key Usage: 检查是TLS Web Server Authentication还是Client Authentication。Signature Algorithm: 确认是sha256WithRSAEncryption。
5.2 查看私钥信息
1 | openssl rsa -in server.key -text -noout |
- 可以确认私钥长度(如 2048 bit)。
- 可以确认私钥是否加密(如果有
Proc-Type: 4,ENCRYPTED则表示加密)。
5.3 验证证书链
1 | # 验证 server.crt 是否信任 ca.crt |
- 如果返回
error 20 at 0 depth lookup: unable to get local issuer certificate,说明找不到颁发者。
5.4 调试神器:s_client
模拟客户端发起 TLS 握手,查看服务器返回的证书链。
1 | openssl s_client -connect example.com:443 -servername example.com |
-connect: 目标地址。-servername: SNI 扩展,指定虚拟主机名(多域名证书必需)。- 输出分析:
- 查看
Certificate chain部分,确认服务器发送了完整的证书链。 - 查看
Verify return code: 0 (ok)确认验证通过。 - 查看
Protocol和Cipher确认加密套件强度。
- 查看
6. 格式转换
不同平台需要不同的证书格式,OpenSSL 是转换工具。
6.1 PEM 转 DER (二进制)
1 | openssl x509 -in cert.pem -outform der -out cert.der |
6.2 PEM 转 PKCS12 (包含私钥,用于 Windows/Java)
1 | openssl pkcs12 -export -out cert.pfx -inkey server.key -in server.crt -certfile ca.crt |
- 会提示设置导出密码。
6.3 PKCS12 转 PEM
1 | openssl pkcs12 -in cert.pfx -out cert.pem -nodes |
-nodes: 导出的私钥不加密。
7. 配置文件 openssl.cnf 详解
在生产环境中,为了统一管理策略(如强制密钥长度、强制扩展属性),通常不依赖命令行参数,而是修改 openssl.cnf。
默认路径通常在 /etc/ssl/openssl.cnf 或 /usr/lib/ssl/openssl.cnf。
关键配置段示例:
1 | [ CA_default ] |
basicConstraints = critical, CA:true: 标记为 CA 证书,且关键扩展不可忽略。keyUsage: 限制私钥只能用于数字签名和密钥加密,不能用于身份认证等其他用途。critical: 标记为关键扩展,如果客户端不认识该扩展,必须拒绝连接(安全增强)。
8. 安全最佳实践总结
- 密钥长度: RSA 至少 2048 位,推荐 4096 位。或者使用 ECC (P-256)。
- 算法: 签名算法必须使用 SHA-256 或更高。禁止 MD5/SHA1。
- SAN: 必须配置 SAN,不要依赖 CN。
- 私钥保护:
- 文件权限设置为
600(chmod 600 *.key)。 - 不要将私钥提交到代码仓库。
- 定期轮换密钥。
- 文件权限设置为
- 证书有效期: 不要设置过长(如 10 年)。公共 CA 通常最长 1 年。内部 CA 建议 1-2 年,配合自动化轮换。
- 扩展用途 (EKU): 严格区分
serverAuth和clientAuth,不要混用。 - 证书链: 服务器配置时,必须发送完整证书链(服务器证书 + 中间证书),否则旧客户端或 Java 客户端可能无法验证。
9. 常见错误速查表
| 错误信息 | 可能原因 | OpenSSL 排查命令 |
|---|---|---|
unable to get local issuer certificate |
缺少 CA 根证书或中间证书 | openssl verify -CAfile ca.crt server.crt |
certificate has expired |
证书过期 | openssl x509 -in cert.crt -noout -dates |
x509: certificate relies on legacy Common Name field |
缺少 SAN 扩展 | openssl x509 -in cert.crt -text -noout | grep -A1 "Subject Alternative Name" |
remote error: tls: bad certificate |
证书用途不对 (如客户端用了服务器证书) | openssl x509 -in cert.crt -text -noout | grep "Extended Key Usage" |
certificate is valid for A, not B |
访问域名与证书 SAN 不匹配 | 检查 openssl s_client 连接时的域名 |
通过以上指南,您应该能够熟练掌握 OpenSSL 的核心用法,独立完成证书生成、管理、调试和故障排查。
1 | # 1. 生成私钥 |

