Nginx仅接受PEM格式证书和私钥,PFX与JKS需经OpenSSL无损提取:PFX导出server.crt(含服务器证+中间证)和未加密server.key(chmod 600),JKS须先转PKCS12再拆解;证书链顺序、无BOM、无空行、私钥格式合规是HTTPS成功启用的关键。

Nginx 只接受 PEM 格式的证书和私钥,而 PFX(Windows/IIS 常用)和 JKS(Java/Tomcat 常用)是加密容器格式,不能直接使用。所谓“无损迁移”,核心不是改后缀,而是完整提取、正确排序、严格权限控制——漏掉中间证书、私钥被加密、文件权限过高,都会导致 HTTPS 启动失败或浏览器报“不安全”。
从 PFX 提取可用的 server.crt 与 server.key
PFX 文件通常包含三样东西:服务器证书、私钥、一个或多个中间证书。Nginx 需要两个独立文件:server.crt(含服务器证书 + 中间证书) 和 server.key(明文私钥)。
- 先导出私钥(不加密,适合测试;生产环境建议保留密码,后续再加):
openssl pkcs12 -in cert.pfx -nocerts -nodes -out server.key - 再导出证书内容(推荐先导出完整 PEM,再手动拆分):
openssl pkcs12 -in cert.pfx -out cert.pem -nodes - 用文本编辑器打开 cert.pem,按顺序提取:
- 第一个 -----BEGIN CERTIFICATE----- 到对应 -----END CERTIFICATE----- → 保存为 server.crt
- 后续所有 -----BEGIN CERTIFICATE----- 块 → 合并为 ca-bundle.crt,然后追加到 server.crt 后面(cat ca-bundle.crt >> server.crt)
- 单独的 -----BEGIN PRIVATE KEY----- 块 → 保存为 server.key
- 设置私钥权限:
chmod 600 server.key(Nginx 拒绝加载权限大于 600 的私钥)
从 JKS 转 PEM:必须经由 PKCS12 中转
JKS 是 Java 密钥库,OpenSSL 无法直读。必须先用 keytool 导出为标准 PKCS12(即 .p12),再用 OpenSSL 拆解。
- 将 JKS 转为 P12:
keytool -importkeystore -srckeystore app.jks -destkeystore app.p12 -srcstoretype JKS -deststoretype PKCS12
过程中会提示输入源密钥库密码和目标密钥库新密码(建议设相同,避免后续输错) - 若 JKS 含别名(如 tomcat),且导出失败提示 “no certificate matches alias”,请加参数:
-srcalias tomcat - 从 P12 提取私钥与证书链:
openssl pkcs12 -in app.p12 -nocerts -nodes -out app.key
openssl pkcs12 -in app.p12 -clcerts -nokeys -out app.crt
注意:-clcerts 默认只导出服务器证书;如需完整链,仍建议用 -out full.pem -nodes 后手动拆分
PEM 内容结构与 Nginx 配置要点
Nginx 的 ssl_certificate 指令接收的是“证书链文件”,不是单张证书;它要求内容为 PEM 编码、无 BOM、无多余空行、顺序为:服务器证书 → 中间证书(可多个)。
- 检查 server.crt 是否符合结构:
打开文件,应看到类似:-----BEGIN CERTIFICATE----- [服务器证书 Base64] -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- [中间证书 Base64] -----END CERTIFICATE-----
- 私钥格式应为 RSA 或 PKCS#8:
合法开头是 -----BEGIN RSA PRIVATE KEY----- 或 -----BEGIN PRIVATE KEY-----;若为后者且 Nginx 报错,可用此命令转换:
openssl rsa -in server.key -out server.key - Nginx 配置示例(关键两行):
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
常见故障与规避建议
很多问题不是命令错了,而是细节没控住。
- 浏览器仍提示不安全 → 大概率证书链缺失:用 openssl verify -CAfile ca-bundle.crt server.crt 验证是否能连通根证书
- Nginx 启动失败,报 “no start line” → 文件含不可见字符(如 Windows 编辑器插入的 BOM)、空行、或复制时多出空格;用 cat -A server.crt 查看隐藏符号
- 提示 “private key file has world permissions” → 私钥权限不是 600;执行 chmod 600 server.key 即可
- 在线工具慎用 → PFX/JKS 含私钥,上传到第三方网站等于交出 HTTPS 控制权;仅限测试环境临时验证


















