手当たり次第に書くんだ

飽きっぽいのは本能

PEM 形式の証明書・秘密鍵を 1 行に整形する方法 – SAML や Kubernetes Secret で扱う時の注意点

SAML、OIDC、Kubernetes Secret、Ansible 変数、JSON / YAML の設定値などで、PEM 形式の証明書や秘密鍵を 1 行の文字列として扱いたい場面があります。

PEM は本来、BEGIN 行、Base64 本体、END 行を含む複数行の形式です。ただし、アプリケーションや設定項目によっては、Base64 本体だけを改行なしで渡す必要があります。この記事では、証明書や秘密鍵を 1 行に整形する方法と、扱う時の注意点を整理します。

PEM 形式の構造

PEM 形式の証明書は、次のように BEGIN / END 行と、その間の Base64 文字列で構成されます。

-----BEGIN CERTIFICATE-----
MIID...複数行の Base64...
-----END CERTIFICATE-----

秘密鍵も同じように PEM 形式です。ただし、ヘッダーは鍵の種類によって変わることがあります。

-----BEGIN PRIVATE KEY-----
MIIE...複数行の Base64...
-----END PRIVATE KEY-----
種類よくある BEGIN 行用途
証明書BEGIN CERTIFICATEサーバー証明書、CA 証明書
秘密鍵BEGIN PRIVATE KEYPKCS#8 形式の秘密鍵
RSA 秘密鍵BEGIN RSA PRIVATE KEY従来形式の RSA 秘密鍵
CSRBEGIN CERTIFICATE REQUEST証明書署名要求

証明書を 1 行に整形する

証明書の Base64 本体だけを 1 行にする場合は、BEGIN / END 行を除外し、残りの行を改行なしで連結します。

awk '!/-----BEGIN CERTIFICATE-----/ && !/-----END CERTIFICATE-----/ { printf "%s", $0 }' server.crt
echo

printf "%s" を使うことで、元の改行を出力せずに連結できます。最後の echo は、ターミナル表示上の末尾改行を付けるためのものです。

秘密鍵を 1 行に整形する

秘密鍵も同じ考え方で整形できます。ただし、秘密鍵は証明書よりも機密性が高いため、シェル履歴、クリップボード、ログ、CI/CD の出力に残さないように注意します。

awk '!/-----BEGIN PRIVATE KEY-----/ && !/-----END PRIVATE KEY-----/ { printf "%s", $0 }' server.key
echo

RSA 秘密鍵の場合は BEGIN / END 行が異なるため、次のように条件を変えます。

awk '!/-----BEGIN RSA PRIVATE KEY-----/ && !/-----END RSA PRIVATE KEY-----/ { printf "%s", $0 }' server-rsa.key
echo

汎用的に BEGIN / END 行を除外する

ファイルの種類を限定せず、PEM の BEGIN / END 行をすべて除外して Base64 本体だけを連結するなら、次のように書けます。

awk '!/^-----BEGIN / && !/^-----END / { printf "%s", $0 }' input.pem
echo

証明書、秘密鍵、CSR などで共通して使えます。ただし、複数の証明書が連結された CA バンドルに対して実行すると、複数証明書の Base64 がそのまま連結されます。用途によっては不正な値になるため注意が必要です。

改行を として保持したい場合

設定項目によっては、Base64 本体だけではなく、PEM 全体を 付きの文字列として渡す必要があります。この場合は、改行を削除するのではなく、改行文字をエスケープします。

awk '{ printf "%s\n", $0 }' server.crt

どちらが必要かはアプリケーション次第です。Base64 本体だけを要求しているのか、PEM 全体を文字列として要求しているのかを確認してから整形します。

要求される形式渡す内容
Base64 本体のみBEGIN / END を除外し、改行も除去するSAML の一部設定、証明書フィンガープリント以外の証明書欄
PEM 全体BEGIN / END を含め、改行を保持または 化するKubernetes Secret、環境変数、JSON 設定
ファイルパス文字列化せずファイルとして配置するnginx、Apache、Postfix、Dovecot

Kubernetes Secret や Ansible で扱う場合

Kubernetes Secret や Ansible では、無理に 1 行化するより、ファイルとして読み込ませる方が安全で管理しやすい場合があります。

kubectl create secret tls web-tls   --cert=server.crt   --key=server.key   -n example

Ansible では、証明書や秘密鍵を変数に直接貼り付けるより、Vault で暗号化したファイルやテンプレートとして扱う方が、漏洩リスクとレビューのしやすさのバランスを取りやすくなります。

秘密鍵を 1 行化する時の注意点

  • 秘密鍵をターミナル履歴に残さない
  • CI/CD のログに出力しない
  • クリップボード経由で長時間保持しない
  • チャットやチケットに貼り付けない
  • Base64 化されていても暗号化されているとは考えない
  • 可能ならファイルとして配置し、権限を限定する

Base64 は暗号化ではありません。PEM の中身を 1 行にしても、秘密鍵は秘密鍵のままです。扱いやすくするための整形であって、安全性を高める処理ではありません。

まとめ

PEM 形式の証明書や秘密鍵を 1 行に整形する場合は、BEGIN / END 行を除外して Base64 本体を連結します。一方で、アプリケーションによっては PEM 全体を 付きで渡す必要があるため、要求される形式を先に確認することが重要です。

特に秘密鍵は、1 行化すると設定値として貼り付けやすくなる分、ログや履歴に残りやすくなります。証明書の整形は便利な作業ですが、秘密鍵の管理境界を崩さないように扱うべきです。

参考
書籍
参考書籍

暗号技術入門 第3版 秘密の国のアリス

公開鍵暗号、電子署名、証明書など、TLS や内部 PKI の前提になる暗号技術を確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

PEM 形式の証明書・秘密鍵を 1 行に整形する方法 – SAML や Kubernetes Secret で扱う時の注意点

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る