web-dev-qa-db-ja.com

PEMファイルを分割する方法

注:これは実際には質問ではありませんが、答えはすでに見つかりましたが、ここでは簡単に見つけられなかったため、できるように投稿します他人のためになる。

質問:連結された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-----/' '{*}'
40
Cerber

これは 以前はStackOverflowで回答済み でした:

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

2016年3月29日編集:@slugchewer answer を参照

16
Cerber

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-----/' '{*}'
18
squidpickles

マルチ証明書PEMバンドルから単一の証明書を取得する場合は、以下を試してください。

$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
    openssl pkcs7 -print_certs | \
    awk '/subject.*CN=Host.domain.com/,/END CERTIFICATE/'
  • 最初の2つのopensslコマンドはPEMファイルを処理し、各証明書の前に、プリペンド"subject:"および"issuer:"行でそれを吐き出します。 PEMがすでにこの方法でフォーマットされている場合、必要なのは最後のawkコマンドだけです。
  • Awkコマンドは、CN(共通名)文字列に一致する個々のPEMを吐き出します。

source1source2

6
cmcginty

また、 PEMファイルBEGIN/ENDブロック内のキー/証明書のコレクションにすぎないので、それが単に1つまたは2つの興味深いエンティティを含む単一のファイル...

3
mgalgs

証明書と認証局チェーンを連結したフルチェーン証明書(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のコンテンツの最後から最も長い部分文字列

2
Fabio

うーん...私が解決策を準備したのとほとんど同じ方法で(提案された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)。

0