如何拆分 PEM 文件

Cer*_*ber 49 shell openssl awk x509

注意:这不是一个真正的问题,因为我已经找到了答案,但是由于我在这里不容易找到它,所以我将其发布,以便它可以使其他人受益。

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

答案(原文)来源):

cat $file|awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'
Run Code Online (Sandbox Code Playgroud)

如果末尾有一个空行,这可能会留下一个空文件,例如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"}' 
Run Code Online (Sandbox Code Playgroud)

回答 29/03/2016

按照@slugchewer answercsplit可能是一个更清晰的选择:

csplit -f cert- $file '/-----BEGIN CERTIFICATE-----/' '{*}'
Run Code Online (Sandbox Code Playgroud)

Joh*_*mke 30

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
Run Code Online (Sandbox Code Playgroud)

  • 我认为这优于 awk 解决方案,让 openssl 进行解析 + 你得到转换。 (3认同)
  • 知道如何以这种方式获得第三个证书吗? (2认同)

squ*_*les 22

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

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

split -p "-----BEGIN CERTIFICATE-----" collection.pem individual-
Run Code Online (Sandbox Code Playgroud)

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

csplit -s -z -f individual- collection.pem '/-----BEGIN CERTIFICATE-----/' '{*}'
Run Code Online (Sandbox Code Playgroud)

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

-z 不创建空文件

  • 抱歉,我的系统(busybox、fedora、centos)都没有在 split 上显示 `-p` 选项(也没有 [我阅读的联机帮助页](http://linux.die.net/man/1/split))。也许您正在使用特殊的二进制文件/包 (3认同)
  • @Cerber 可以尝试使用“csplit”...(参见上面的编辑) (2认同)
  • 与“csplit”配合良好! (2认同)

Cer*_*ber 18

这是以前在 StackOverflow 上回答的

awk '
  split_after == 1 {n++;split_after=0}
  /-----END CERTIFICATE-----/ {split_after=1}
  {print > "cert" n ".pem"}' < $file
Run Code Online (Sandbox Code Playgroud)

29/03/2016 编辑:见@slugchewer答案

  • 受此启发,我创建了一个 awk 脚本,将证书和密钥拆分为单独的文件:https://gist.github.com/jinnko/d6867ce326e8b6e88975 (3认同)

小智 7

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

\n\n

例如:

\n\n
# content of /path/to/fullchain.pem\n-----BEGIN CERTIFICATE-----\nsome long base64 string containing\nthe certificate\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nanother base64 string\ncontaining the first certificate\nin the authority chain\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nanother base64 string\ncontaining the second certificate\nin the authority chain\n(there might be more...)\n-----END CERTIFICATE-----\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
#\xc2\xa0load the certificate into a variable\nFULLCHAIN=$(</path/to/fullchain.pem)\nCERTIFICATE="${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"\nCHAIN=$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed \'/./,$!d\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

解释:

\n\n

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

\n\n

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

\n\n

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

\n\n

作为快速参考(虽然您可以在此处找到有关 bash 中的字符串操作的更多信息)找到有关 bash 中的字符串操作的更多信息):

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n


cmc*_*nty 6

如果您想从多证书 PEM 包中获取单个证书,请尝试:

$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
    openssl pkcs7 -print_certs | \
    awk '/subject.*CN=host.domain.com/,/END CERTIFICATE/'
Run Code Online (Sandbox Code Playgroud)
  • 前两个openssl命令将处理PEM文件和与吐出与预先计划回退"subject:""issuer:"每个证书前行。如果您的 PEM 已经以这种方式格式化,那么您需要的只是最后的awk命令。
  • awk 命令将输出与 CN(通用名称)字符串匹配的单个 PEM。

来源 1 , 来源 2