OpenSSL 最佳实践
FreeGuideOnline
最新
2026-07-14
bash
生成 4096 位的 RSA 私钥并使用 AES-256 加密保护
openssl genpkey -algorithm RSA -out private.key -aes256 -pkeyopt rsa_keygen_bits:4096
- 避免使用 1024 位 RSA,其已被视为不安全。
- 建议为私钥设置强密码短语(至少 12 字符,包含大小写字母、数字和符号)。
### 1.2 椭圆曲线(ECDSA):优先使用现代曲线
```bash
# 生成基于 prime256v1 (即 secp256r1) 的 ECC 私钥
openssl ecparam -genkey -name prime256v1 -out ec_private.key
- 推荐曲线:
prime256v1、secp384r1、secp521r1。 - 避免使用
secp112r1、secp160r1等较短的曲线以及已弃用的secp256k1(仅用于比特币,不推荐用于 TLS)。 - 使用
openssl ecparam -list_curves查看支持的曲线。
1.3 EdDSA(如果软件支持)
# 生成 Ed25519 私钥(现代应用首选)
openssl genpkey -algorithm Ed25519 -out ed_private.key
- Ed25519 提供更高的安全性与性能,且没有错误实现的风险。在兼容性允许的情况下优先选择。
2. 证书签名请求(CSR)与证书管理
2.1 创建 CSR 时使用 SHA-256 或更强哈希
openssl req -new -key private.key -out request.csr -sha256
- 避免 MD5 和 SHA-1,二者已被证明存在碰撞风险。
- 在配置文件
openssl.cnf中设置默认哈希:default_md = sha256
2.2 规范化证书扩展
使用配置文件定义密钥用法和扩展属性,而不是依赖交互式命令行:
[ req ]
distinguished_name = req_dn
req_extensions = v3_req
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = example.com
DNS.2 = www.example.com
然后生成 CSR:
openssl req -new -config myconfig.cnf -key private.key -out request.csr
2.3 自签证书仅限测试环境
生产环境必须使用受信任 CA 签发的证书。若需自签用于内网,应同时部署内部 CA 并强制所有客户端信任该 CA。
3. 私钥保护与权限管理
3.1 严格限制文件权限
chmod 600 private.key
chown root:root private.key
3.2 加密存储私钥
- 始终用 AES-256 加密私钥文件(生成时使用
-aes256参数)。 - 若密钥需要无密码用于服务自动启动,可使用密钥管理服务(如 HashiCorp Vault)或硬件安全模块(HSM),而不应将明文私钥放在磁盘上。
3.3 传输保护
- 使用
scp、sftp或加密通道传输密钥,禁止通过邮件或不安全的协议发送。 - 传输后立即从发送端删除源文件(若不再需要)。
4. 现代 TLS 配置:协议与密码套件
4.1 仅启用 TLS 1.2 与 TLS 1.3
在 OpenSSL 配置(或应用配置)中禁用 SSLv2、SSLv3、TLSv1.0、TLSv1.1:
ssl_protocols TLSv1.2 TLSv1.3;
(Apache、Nginx 等应用会调用 OpenSSL,此处以 Nginx 为例。)
4.2 优先使用强密码套件
对于 TLS 1.2,推荐以下 OpenSSL 密码字符串:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
- 禁止使用 RC4、3DES、CBC 模式密码套件(易受 BEAST、Lucky13 攻击)。
- 禁止使用匿名密钥交换(如
aNULL)和出口级密码。
4.3 TLS 1.3 简化了密码配置
TLS 1.3 默认仅使用安全的 AEAD 密码,无需手动挑选。确保客户端和服务端均支持 TLS 1.3。
5. 证书链与信任验证
5.1 配置完整的证书链
将服务器证书与中间 CA 证书按顺序合并:
cat server.crt intermediate.crt root.crt > fullchain.pem
某些服务器(如 Nginx)需要你单独指定中间证书:
ssl_certificate fullchain.pem;
ssl_certificate_key private.key;
5.2 使用 OpenSSL 验证链
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt
- 确保输出
OK。 - 定期使用
openssl s_client -connect example.com:443 -showcerts检查服务器实际返回的证书链。
5.3 避免使用非标准根证书
只信任主流浏览器和操作系统内置的根证书。内部 CA 必须将根证书安全分发到所有客户端。
6. 证书生命周期自动化
6.1 监控证书到期
使用脚本或监控工具(如 check_ssl_cert、ssl-cert-check)提前 30 天告警:
openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
6.2 自动化续期(推荐 Let's Encrypt)
使用 certbot 或 acme.sh 实现自动申请和续签。
- 对内部环境,建立 ACME 服务器(如
step-ca)统一管理内部证书。
7. 强化 OpenSSL 配置与安全杂项
7.1 更新 OpenSSL 版本
始终使用受支持的最新稳定版(如 3.0 LTS 或 3.1+)。旧版本(1.0.2 及以下)已停止维护,存在高危漏洞。
openssl version
- 关注 OpenSSL 安全公告,及时打补丁。
7.2 使用 -rand 或 -writerand 保证熵池质量
在生成密钥时,可指定随机种子文件以提高熵质量(Linux 下通常无需额外指定,但嵌入式系统必须注意):
openssl genpkey -algorithm RSA -out key.pem -aes256 -rand /dev/urandom
7.3 配置 OCSP Stapling
在服务器端开启 OCSP Stapling,减少客户端查询 CA 的延迟并保护隐私:
- Nginx:
ssl_stapling on; ssl_stapling_verify on; - 需要提供完整的信任链以便服务器获取 OCSP 响应。
7.4 启用 HSTS(HTTP 严格传输安全)
虽然不是 OpenSSL 直接负责,但在 Web 服务器配置中设置 Header:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
8. 调试与安全审计工具
8.1 使用 testssl.sh 全面检查
./testssl.sh https://example.com
该工具会评估协议、密码套件、证书漏洞等。
8.2 使用 sslscan 或 nmap 快速扫描
sslscan example.com:443