注:これは実際には質問ではありませんが、答えはすでに見つかりましたが、ここでは簡単に見つけられなかったため、できるように投稿します他人のためになる。
質問:連結されたPEMファイルをApache/mod_sslディレクティブ SSLCACertificateFile で使用されるものとして読み取る方法は?
Answer(original)( source ):
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"}'
回答29/03/2016:
@slugchewer answer に続いて、csplit
を使用すると、より明確なオプションになる可能性があります。
csplit -f cert- $file '/-----BEGIN CERTIFICATE-----/' '{*}'
これは 以前はStackOverflowで回答済み でした:
awk '
split_after == 1 {n++;split_after=0}
/-----END CERTIFICATE-----/ {split_after=1}
{print > "cert" n ".pem"}' < $file
2016年3月29日編集:@slugchewer answer を参照
Awkスニペットはさまざまな部分を抽出するために機能しますが、どのセクションがkey/cert/chainであるかを知る必要があります。特定のセクションを抽出する必要があり、これは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
split
コマンドはほとんどのシステムで使用でき、その呼び出しは覚えやすいでしょう。
ファイルがある場合collection.pem
分割したいindividual-*
ファイル、使用:
split -p "-----BEGIN CERTIFICATE-----" collection.pem individual-
split
がない場合は、csplit
を試すことができます。
csplit -f individual- collection.pem '/-----BEGIN CERTIFICATE-----/' '{*}'
マルチ証明書PEMバンドルから単一の証明書を取得する場合は、以下を試してください。
$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
openssl pkcs7 -print_certs | \
awk '/subject.*CN=Host.domain.com/,/END CERTIFICATE/'
openssl
コマンドはPEMファイルを処理し、各証明書の前に、プリペンド"subject:"
および"issuer:"
行でそれを吐き出します。 PEMがすでにこの方法でフォーマットされている場合、必要なのは最後のawk
コマンドだけです。また、 PEMファイル はBEGIN
/END
ブロック内のキー/証明書のコレクションにすぎないので、それが単に1つまたは2つの興味深いエンティティを含む単一のファイル...
証明書と認証局チェーンを連結したフルチェーン証明書(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')
_
説明:
Awkまたはopenssl(強力なツールですが、常に利用できるとは限らない、つまりDocker Alpineイメージ)を使用する代わりに、bash文字列操作を使用できます。
_"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
_:FULLCHAINのコンテンツの最後から、最長の部分文字列の一致を返し、削除された_-----END CERTIFICATE-----
_を連結します。 _*
_は、_-----END CERTIFICATE-----
_以降のすべての文字に一致します。
$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d')
:FULLCHAINのコンテンツの先頭から、最短の部分文字列の一致を返し、先頭の新しい行を削除します。同様に、_*
_は、_-----END CERTIFICATE-----
_の前のすべての文字に一致します。
クイックリファレンスとして(bashでの文字列操作の詳細については here ):
_${VAR#substring}
_ = VARのコンテンツの先頭からの最短の部分文字列
_${VAR%substring}
_ = VARのコンテンツの末尾からの最も短い部分文字列
_${VAR##substring}
_ = VARのコンテンツの先頭からの最長の部分文字列
_${VAR%%substring}
_ = VARのコンテンツの最後から最も長い部分文字列
うーん...私が解決策を準備したのとほとんど同じ方法で(提案されたy @Cerberのように)、この状況が多くの人が持っているように思われることに気付かずに。私のソリューションはほぼ同じロジックに従いますが、いくつかのより基本的なコマンドを使用します。
私のすべての証明書はファイルにあります:certin.pem
c=0
while read line
do
if echo $line | grep END; then
echo $line >> certout$c.pem
c=`expr $c + 1`
else
echo $line
echo $line >> certout$c.pem
fi
done < /tmp/certin.pem
これは基本的に、「END」に到達するまでファイルへの書き込みを続け、その後、インクリメントされた方法で別のファイルへの書き込みを開始します。このように、入力PEMファイルにある証明書の数に応じて、出力ファイル(certout0.pem、certout1.pemなど)の数が "N"になります(certin.pem)。