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 answer,csplit
可能是一个更清晰的选择:
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)
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
不创建空文件
Cer*_*ber 18
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答案
小智 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-----
。
$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed \'/./,$!d\')
:从 FULLCHAIN 的内容开始,返回匹配的最短子串,然后去掉前导新行。同样,*
匹配之前的所有字符-----END CERTIFICATE-----
。
作为快速参考(虽然您可以在此处找到有关 bash 中的字符串操作的更多信息)找到有关 bash 中的字符串操作的更多信息):
\n\n${VAR#substring}
= VAR 内容开头的最短子串
${VAR%substring}
= VAR内容末尾的最短子串
${VAR##substring}
= VAR 内容开头的最长子串
${VAR%%substring}
= VAR 内容末尾的最长子串
如果您想从多证书 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
命令。