命令行工具
unable to load certificate:OpenSSL 证书格式不对怎么办
unable to load certificate ... error:0909006C:PEM routines:get_name:no start line ... Expecting: TRUSTED CERTIFICATEunable to load certificate 的意思是:你给 OpenSSL 的文件里,没有它期望的 PEM 格式证书。 证书本身通常没问题,只是格式不同(DER、PKCS#7、PKCS#12),或者用错了文件(私钥、CSR),或者 PEM 文本在复制时被破坏了。
快速修复
修法是先认出文件格式,再用对应的命令转成 PEM。先看文件到底是什么:
file cert.crt
head -c 64 cert.crt | xxd | head -3
grep -- "-----BEGIN" cert.crt
再用对应的命令:
| 看到的内容 | 格式 | 命令 |
|---|---|---|
-----BEGIN CERTIFICATE----- |
PEM 证书 | 检查是否损坏(见下文) |
二进制,以 30 82 开头 |
DER 证书 | openssl x509 -inform DER -in cert.crt -out cert.pem |
-----BEGIN PKCS7----- 或 .p7b |
PKCS#7 证书包 | openssl pkcs7 -print_certs -in cert.p7b -out chain.pem |
二进制 .pfx / .p12 |
PKCS#12 | openssl pkcs12 -in cert.pfx -nokeys -out chain.pem |
BEGIN PRIVATE KEY / CERTIFICATE REQUEST |
不是证书 | 换成正确的文件 |
各种格式和转换方法见 SSL 格式转换工具。
原因
前 3 种是证书用了 PEM 以外的格式,后 3 种是用错文件、PEM 文本损坏和 OpenSSL 1.1.1 的提示写法。
1. 证书是 DER 编码
Windows 导出时选了“DER 编码二进制 X.509”(DER 是二进制编码),Java 工具和部分 CA 也会给二进制证书,扩展名常常是 .cer 或 .crt。
- 确认:
grep BEGIN什么都找不到;openssl x509 -inform DER -in cert.crt -noout -subject能正常输出。 - 修复: 用表格里的命令转成 PEM。
2. 是 PKCS#7 证书包
PKCS#7 的 .p7b / .p7c 文件只装证书不装私钥,Windows 和一些 CA 平台常用这种格式。
- 确认: 文件以
-----BEGIN PKCS7-----开头;或者是二进制,openssl pkcs7 -inform DER -in file -print_certs能用。 - 修复: 用
-print_certs导出,给 Web 服务器用时站点证书放最前,中间证书在后。
3. 是 PKCS#12 文件
PKCS#12 的 .pfx / .p12 文件同时包含私钥和证书,有密码保护。阿里云、腾讯云下载 IIS 或 Tomcat 格式时拿到的就是它。
- 修复: 证书用
openssl pkcs12 -in cert.pfx -nokeys -out chain.pem,私钥用-nocerts -nodes -out key.pem。用旧算法(如 RC2)生成的文件,在 OpenSSL 3 上可能需要加-legacy。更省事的办法是在云控制台直接下载 Nginx 或 Apache 格式。
4. 用错了文件
把私钥、CSR 或公钥文件传给 openssl x509,报错相同。
- 确认:
grep BEGIN显示PRIVATE KEY、CERTIFICATE REQUEST或PUBLIC KEY。 - 修复: 换成证书文件;查看 CSR 用
openssl req -in file -noout -text。
5. PEM 文本被破坏
从邮件、微信、网页上复制,可能多了空格、行被合并、BEGIN/END 行丢了,或者加了 UTF-8 BOM、Windows 换行符。
- 确认:
cat -A cert.pem | head能看到^M或奇怪字符;BEGIN行的横线数量不对或多了空格。 - 修复: 执行
dos2unix,去掉 BOM,确认每行 64 个 base64 字符,或者重新下载文件。
6. Expecting: TRUSTED CERTIFICATE
这只是 OpenSSL 1.1.1 的 openssl x509 在找不到可用内容时,报出它在找的 PEM 类型名。它同样接受普通的 BEGIN CERTIFICATE 块,所以这句话并不表示你需要一种特殊的“受信任证书”,原因仍是上面几条之一。
各环境修法
各环境最后都要得到 PEM 文件,Nginx、Apache 和宝塔只接受 PEM。
Windows: 证书导出向导里选“Base64 编码 X.509 (.CER)”,直接得到 PEM。
Java: keytool -exportcert -rfc -alias 名称 -keystore store.jks 输出 PEM;不加 -rfc 输出的是 DER。
Nginx / Apache / 宝塔: 只接受 PEM。先转换,再让 ssl_certificate / SSLCertificateFile 指向 PEM 证书链;宝塔里粘贴的也必须是 PEM 文本。
在 Windows 上转换: 没有装 OpenSSL 的 Windows 电脑,可以用 Git for Windows 自带的 openssl,或者在 WSL 里执行上面的命令;也可以在证书管理器(certmgr.msc)里重新导出为 Base64 格式。
Kubernetes: TLS Secret 里存的是 PEM 内容的 base64;把 DER 文件 base64 后放进去,控制器加载不了。
不要这样做
下面 3 种做法解决不了格式问题,其中一种还会泄露私钥。
- 把扩展名改成
.pem就指望能用。 扩展名改变不了编码。 - 因为一个文件加载不了,就重新生成私钥和证书。 转换现有文件即可,很少需要重新签发。
- 把
.pfx和它的密码通过同一个渠道发送。 里面有私钥。
常见问题
怎么快速区分 PEM 和 DER?
PEM 是文本,开头是 -----BEGIN CERTIFICATE----- 这样的行;DER 是二进制,head -c 2 file | xxd 通常显示 3082,这是 ASN.1 长序列的开头。扩展名(.crt、.cer)不能说明编码方式。
CA 发来一个 .p7b 文件,里面有哪些证书?
PKCS#7 是一个容器,可以装站点证书和中间证书。openssl pkcs7 -print_certs -in bundle.p7b 会以 PEM 格式列出它们;如果 .p7b 是二进制,加 -inform DER。
能把证书贴到在线工具里看吗?
证书是公开信息,可以。证书解析工具支持粘贴 PEM 文本。但私钥绝不要粘贴到任何网站。