如何拆分 PEM 文件

如何拆分 PEM 文件

笔记 :这不是一个真正的问题,因为我已经找到了答案,但由于我在这里找不到答案,所以我将发布它,以便它可以帮助其他人。

问题 :如何读取连接的 PEM 文件作为 apache/mod_ssl 指令使用的文件SSLCA证书文件

答案(原文)来源):

cat $file|awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'

如果末尾有空行,例如openssl pkcs7 -outform PEM -in my-chain-file -print_certs,则可能会留下一个空文件。为防止这种情况,请在打印之前检查行的长度:

cat $file|awk 'split_after==1{n++;split_after=0}
   /-----END CERTIFICATE-----/ {split_after=1}
   {if(length($0) > 0) print > "cert" n ".pem"}' 

回答 2016 年 3 月 29 日

关注 @slugchewer回答csplit可能是一个更清晰的选择:

csplit -f cert- $file '/-----BEGIN CERTIFICATE-----/' '{*}'

答案1

awk 代码片段可用于提取不同的部分,但您仍然需要知道哪个部分是密钥/证书/链。我需要提取特定部分,并在 OpenSSL 邮件列表中找到了以下内容:http://openssl.6102.n7.nabble.com/Convert-pem-to-crt-and-key-files-tp47681p47697.html

# Extract key
openssl pkey -in foo.pem -out foo-key.pem

# Extract all the certs
openssl crl2pkcs7 -nocrl -certfile foo.pem |
  openssl pkcs7 -print_certs -out foo-certs.pem

# Extract the textually first cert as DER
openssl x509 -in foo.pem -outform DER -out first-cert.der

答案2

split命令在大多数系统上都可用,并且它的调用可能更容易记住。

collection.pem如果您有一个想要拆分成多个文件的文件individual-*,请使用:

split -p "-----BEGIN CERTIFICATE-----" collection.pem individual-

如果你没有split,你可以尝试csplit

csplit -s -z -f individual- collection.pem '/-----BEGIN CERTIFICATE-----/' '{*}'

-s跳过打印文件大小的输出

-z不创建空文件

答案3

这是之前在 StackOverflow 上回答过

awk '
  split_after == 1 {n++;split_after=0}
  /-----END CERTIFICATE-----/ {split_after=1}
  {print > "cert" n ".pem"}' < $file

编辑 2016/03/29:参见@slugchewer回答

答案4

如果您正在处理完整链证书(即由 letsencrypt / certbot 等生成的证书),它们是证书和证书颁发机构链的串联,则可以使用 bash 字符串操作。

例如:

# content of /path/to/fullchain.pem
-----BEGIN CERTIFICATE-----
some long base64 string containing
the certificate
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
another base64 string
containing the first certificate
in the authority chain
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
another base64 string
containing the second certificate
in the authority chain
(there might be more...)
-----END CERTIFICATE-----

要将证书和证书颁发机构链提取到变量中:

# load the certificate into a variable
FULLCHAIN=$(</path/to/fullchain.pem)
CERTIFICATE="${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
CHAIN=$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d')

解释:

您可以使用 bash 字符串操作,而不必使用 awk 或 openssl(它们是功能强大的工具但并不总是可用,例如在 Docker Alpine 镜像中)。

"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----":从 FULLCHAIN 内容的末尾开始,返回最长的子字符串匹配,然后-----END CERTIFICATE-----在将其剥离时进行连接。*匹配 之后的所有字符-----END CERTIFICATE-----

$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d'):从 FULLCHAIN 内容的开头开始,返回最短的子字符串匹配,然后删除前导换行符。同样,匹配*之前的所有字符-----END CERTIFICATE-----

作为快速参考(你可以在 bash 中找到有关字符串操作的更多信息)这里):

${VAR#substring}= 从 VAR 内容开头开始的最短子字符串

${VAR%substring}= 距 VAR 内容末尾的最短子字符串

${VAR##substring}= 从 VAR 内容开头开始的最长子字符串

${VAR%%substring}= 距 VAR 内容末尾最长的子字符串

相关内容