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
  • 推荐曲线prime256v1secp384r1secp521r1
  • 避免使用 secp112r1secp160r1 等较短的曲线以及已弃用的 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 传输保护

  • 使用 scpsftp 或加密通道传输密钥,禁止通过邮件或不安全的协议发送。
  • 传输后立即从发送端删除源文件(若不再需要)。

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_certssl-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)

使用 certbotacme.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 使用 sslscannmap 快速扫描

sslscan example.com:443