PEM例程:PEM_read_bio:行末格式错误

41

我试图解析embedded.mobileprovision文件中的开发人员证书。首先,我使用

security cms -D -i embedded.mobileprovision

获取base64编码的开发人员证书字符串。

然后,我将字符串每64个字符进行一次分割,并存储在名为dev.cer的文件中。

最后,在文件的第一行添加-----BEGIN CERTIFICATE-----并在文件结尾添加-----END CERTIFICATE-----

在我的Mac电脑上,我右键点击dev.cer文件,所有的开发人员信息都在那里。但是,当我使用openssl x509 -in dev.cer -text –noout时,出现错误:

unable to load certificate
69721:error:0906D066:PEM routines:PEM_read_bio:bad end line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.50.6/src/crypto/pem/pem_lib.c:747:

dev.cer文件如下:

-----BEGIN CERTIFICATE-----
MIIFljCCBH6gAwIBAgIIIP7GMO9cWzYwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
HhcNMTcwNDI5MDMzMDA4WhcNMTgwNDI5MDMzMDA4WjCBiTEaMBgGCgmSJomT8ixk
AQEMCk1ENFA0UTg1WlExMzAxBgNVBAMMKmlQaG9uZSBEZXZlbG9wZXI6IGFtbW1p
IGFtbW1pIChXM1BSS1JDVDRRKTETMBEGA1UECwwKVktRNTZVQ0c4ODEUMBIGA1UE
CgwLYW1tbWkgYW1tbWkxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAwudboPuPnImOssBCw9vISRnnivreVwOuDAu77u47zIU8uTag
bzktX6pF54YToSLQHeOaNNQfZ7idccU2DKVBr3etz/++ca4HNadeUaEm2VWW4kEq
3iKIo1wZZhJJR6bQl4q797U0+f7eEXLKD4fjfidEF+ceAxAsX5YIuokq3K/B+XW3
tKk7D4nCaaCyJ9/+aJkFKT/oOxWRD0NYi5vXpni/3Plj5Qu3kDGrTUQaGCXXjRrA
E3mOVS4M2W5sFoOUpBxcfK7ajs+HUZNp0Gvb04OeD4O0lLTxcNu6omhG3MzOo81F
T+bkdxLM7XkIbNlIjYhyxGRynpgAKmiR9B/oeQIDAQABo4IB8TCCAe0wPwYIKwYB
BQUHAQEEMzAxMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5hcHBsZS5jb20vb2Nz
cDAzLXd3ZHIwMTAdBgNVHQ4EFgQUF8T1dPnBmZfKfG0+lHtczMuGy9owDAYDVR0T
AQH/BAIwADAfBgNVHSMEGDAWgBSIJxcJqbYYYIvs67r2R1nFUlSjtzCCAR0GA1Ud
IASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1Jl
bGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMg
YWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1z
IGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBj
ZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipo
dHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wDgYDVR0P
AQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMBMGCiqGSIb3Y2QGAQIB
Af8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQA1//RUQ+hnCxfzSKO13qtuSb4IUrY5
bjkRKIAUlxN5aYVN5NIzCGxmahlDA/Rjw8MLVA8dWbT0QMSqx5IXC+Ov3JNZlkL0
5+RBuZEtZL7IZp0L3ZrCFtuizaunH9fZWbyFyfLACIYqZqP40N1+wIx1l4Es65Zu
WSeDeQMutda8DpmtCJhrnod9B1vfvDc3FUSmbJbvkLFh2UCgqtE9moLYI8qFMzqe
CQUJdPGdE+2WNv0wM8/cFIG/audSvEADKg1DgO+j6oP+urUe1gLsyzyv10J7/XA4
nmDuP1UNG7O7ADbdEOxhRiB96ZNwgcw9Q0wv9H9jMa+NNti6SxLud2+B
-----END CERTIFICATE----

顺便说一下,我使用了在线证书解码器来解码dev.cer,效果不错。这是链接:

https://www.sslshopper.com/certificate-decoder.html

这个网站建议使用openssl,但是失败了。


12
我知道问题出在哪里:在这行结尾处缺少一个短横线“-”,应该是-----END CERTIFICATE-----。请注意补上短横线以解决问题。 - sunnycomes
12个回答

62

我和sunnycomes遇到了同样的问题,他的评论是正确的。我在文件的最后一行缺少一个'-'。之前我的代码是:


-----END CERTIFICATE----

并将其更改为:

-----END CERTIFICATE-----

问题已解决。我学到了从终端复制证书文本时必须小心。


多么愚蠢的错误,感谢你的答案,上帝保佑你 ;) - Aleksander Lech

53

额外说明: 当 pem 文件包含 CA 和子 CA 链时,请确保 -----END CERTIFICATE---- -----BEGIN CERTIFICATE----- 不在同一行上。


1
这个!由于某种原因,我的证书提供商(Sectigo通过Namecheap)改变了他们系统的输出。去年我可以无问题地使用cat命令,但今年这样做会导致END和BEGIN在同一行上,从而触发错误! - jerclarke

32

简而言之

请确保在开始和结束标签周围恰好有五个破折号-----

更多关于PEM证书的信息

正确的证书格式

有关证书文本编码的官方RFC 7468文件规定如下:

  • 每个证书的内容必须用BEGIN CERTIFICATEEND CERTIFICATE标记括起来,例如:

    -----BEGIN CERTIFICATE-----
    bGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3Vt...
    -----END CERTIFICATE-----
    
  • 标签本身必须在行开头有五个短横线-----,在行末也必须有五个短横线-----

  • 常见错误

    • 复制粘贴证书时在开头或结尾意外省略了一个短横线

    • 同一行上有两个封装边界符,如下所示:

    • ----END CERTIFICATE----------BEGIN CERTIFICATE-----
      

      如果在同一行结束并直接开始新的证书,则不起作用,因为会有十个破折号而不是五个破折号,证书解析器将无法正确检测标记。

      在开始标记后或结束标记前有一个空行。

      正确链接证书

      一些Web服务器需要所有SSL / TLS(根,中间和最终用户)证书放在一个文件中,但CA通常会单独发送所有证书,因此您需要手动连接它们。 但是,在连接它们时要注意它们的顺序很重要!

      链接证书的正确顺序是:

      1. 最终用户证书
      2. 所有中间证书
      3. 根证书

      要正确连接所有证书,您可以使用以下Bash命令:

      cat end-user.crt <(echo) intermediate.pem <(echo) root.crt > bundled.crt
      

      请务必将 end-user.crtintermediate.pemroot.crt 替换为您自己的文件名。

      顺便说一下:.pem.crt 都是有效的 SSL 证书文件结尾/编码。 您可以在此处阅读有关 SSL 文件的更多信息。


13

我曾经遇到一个意外情况,我的链式证书出现了一个非常愚蠢的错误:

-----END CERTIFICATE----------BEGIN CERTIFICATE-----

应该是

-----END CERTIFICATE----- -----BEGIN CERTIFICATE-----


你解决了一个长达三天的头疼问题。 - martin kimani
1
太棒了,我也执行了"cat"命令,出现了相同的错误,我都快抓狂了,不知道为什么它不工作!非常感谢你。 - Gianpaolo Papa

7

当我在存储私钥(用于在SwiftMailer中签署电子邮件)时,遇到了相同的问题(同一错误消息)。一开始它是正常工作的,然后突然停止工作。

问题在于,一开始我只是在测试,没有担心格式化代码。测试后,我选择将密钥放入一个变量中,并在函数中返回。这样做时,我无意间在密钥内容中插入了多个制表符,如您在图像中所见。最好将内容保存在单独的文件中,其中没有不必要的/额外字符。

输入图像描述.


4
顺便说一下,在代码中嵌入您的私钥似乎是一个非常糟糕的想法。 - a3y3
2
谢谢,你帮我省了好几个小时! - Shahin Ghasemi

5

朋友们,请注意!

不要使用 "cat AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSADomainValidationSecureServerCA.crt > /tmp/commercial_ca.crt.",否则会创建错误的 .crt 文件。

方法如下:

1. 以 root 身份登录,将证书复制并粘贴到文本文件中(使用 Vi、nano 或 Notepad),并将其保存为 commercial.crt。将该文件放置在以下目录中:/opt/zimbra/ssl/zimbra/commercial/。

2. 以 root 身份登录,使用文本编辑器 nano 或 Vi 打开您收到的 CAbundle ZIP 文件,并将其另存为 commercial_ca.crt。将该文件放置在以下目录中:/opt/zimbra/ssl/zimbra/commercial/。

3. 以 Zimbra 用户身份验证 /opt/zimbra/ssl/zimbra/commercial/ 目录。

/opt/zimbra/bin/zmcertmgr verifycrt comm commercial.key commercial.crt commercial_ca.crt

部署为Zimbra用户在/tmp/目录下

/opt/zimbra/bin/zmcertmgr deploycrt comm commercial.crt commercial_ca.crt

zmcontrol restart

https://ssl.comodo.com/support/certificate-installation---zimbra-server.php获取有趣的信息!

  • 如果您遇到权限错误,请验证您是否拥有*.crt文件。

chown zimbra.zimbra /opt/zimbra/ssl/zimbra/commercial/*.crt(作为root用户)

chmod 700 /opt/zimbra/ssl/zimbra/commercial/*.crt(作为zimbra用户)


Zimbra是什么,它是否必要? - icedwater
看起来这只是他在那台机器上的用户名。 - ShapeOfMatter

4
我正在从.env文件中读取密钥。使用双引号将密钥括起来可以解决问题。
出现错误:
KEY=-----BEGIN PRIVATE KEY-----\nMIIJQgIB.....\n-----END PRIVATE KEY-----\n

工作内容:

KEY="-----BEGIN PRIVATE KEY-----\nMIIJQgIB.....\n-----END PRIVATE KEY-----\n"

我能看到一些换行符,这是有意为之吗? 如果密钥不在单行上保持,这个方法还能起作用吗? - Nebulosar
我正在读取包含跨越多行的键的.env文件。对我来说,错误是由于在引用字符串末尾没有换行符所致。我在构建步骤中使用了一个脚本来自动添加一个换行符[[ $KEY != *$'\n' ]] && KEY="${KEY}\n" - Besworks

3
它的工作原理如下:tls.crt
-----BEGIN CERTIFICATE-----
the content of certificate.crt
the content of ca_bundle.crt
-----END CERTIFICATE-----

2
如果您通过以下命令生成crt文件,则会生成错误的输出。
cat yourdomain.crt yourdomain.ca-bundle >> cert_chain.crt

你需要做的是手动复制这些文件内容并粘贴。
-----BEGIN CERTIFICATE-----
the content of yourdomain.crt
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
the content of yourdomain.ca_bundle.crt
-----END CERTIFICATE-----

完成后,请使用以下命令进行测试
openssl x509 -text -noout -in cert_chain.crt

1
另一种可能导致此错误的变体是在页眉之后或页脚之前有空行。例如:
-----BEGIN PRIVATE KEY-----

base64-encoded-stuff-here

-----END PRIVATE KEY-----

解决方法是删除空行:

-----BEGIN PRIVATE KEY-----
base64-encoded-stuff-here
-----END PRIVATE KEY-----

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接