SAML、OIDC、Kubernetes Secret、Ansible 変数、JSON / YAML の設定値などで、PEM 形式の証明書や秘密鍵を 1 行の文字列として扱いたい場面があります。
ただし、「PEM を 1 行にする」と言っても、実際には 2 つの意味があります。1 つは BEGIN / END 行を除いた Base64 本体だけを 1 行にすることです。もう 1 つは BEGIN / END 行を含む PEM 全体を、改行をエスケープした文字列として扱うことです。この 2 つを混同すると、SAML 設定、Kubernetes Secret、アプリケーション設定で失敗しやすくなります。
PEM 形式の構造
PEM 形式の証明書は、BEGIN 行、Base64 本体、END 行で構成されます。
-----BEGIN CERTIFICATE-----
MIID...複数行の Base64...
-----END CERTIFICATE-----秘密鍵も同じように PEM 形式で表現されます。ただし、ヘッダーは鍵の種類によって異なります。
-----BEGIN PRIVATE KEY-----
MIIE...複数行の Base64...
-----END PRIVATE KEY-----ここで大事なのは、BEGIN / END 行も含めて PEM 形式であるという点です。証明書を扱う設定項目によっては、Base64 本体だけを求めるものもあれば、BEGIN / END 行を含む PEM 全体を求めるものもあります。
Base64 本体だけを 1 行にする場合
SAML の証明書設定などでは、BEGIN / END 行を除き、Base64 本体だけを 1 行にして貼り付ける形式があります。この場合は、PEM 全体ではなく、証明書本体の Base64 文字列だけが必要です。
awk 'NF && $0 !~ /-----BEGIN/ && $0 !~ /-----END/ { printf "%s", $0 }' server.crtこの処理では、空行、BEGIN 行、END 行を除外し、Base64 本体だけを改行なしで連結します。SAML IdP / SP の管理画面で証明書欄に貼り付ける場合などは、この形式が求められることがあります。
PEM 全体を 1 行の文字列として扱う場合
一方で、環境変数、JSON、YAML、アプリケーション設定では、BEGIN / END 行を含む PEM 全体を 1 つの文字列として渡したい場合があります。この場合は、改行を削除するのではなく、改行文字を \n としてエスケープします。
python3 -c 'import pathlib; print(pathlib.Path("server.crt").read_text().replace("\\n", "\\\\n"))'この形式では、文字列としては 1 行ですが、アプリケーション側で \n を実際の改行として解釈できる必要があります。単に貼り付ければよいのか、アプリケーション側で復元処理が必要なのかは、利用する製品やライブラリの仕様に依存します。
要求形式を先に確認する
PEM を 1 行に整形するときは、先に「何を要求されているのか」を確認します。Base64 本体だけを要求している設定に、BEGIN / END 行を含めて貼り付けると失敗します。逆に、PEM 全体を求めている設定から BEGIN / END 行を削ってしまうと、証明書や秘密鍵として読み込めません。
| 要求される形式 | 渡す内容 | 代表例 |
|---|---|---|
| Base64 本体のみ | BEGIN / END 行を除外し、改行も除去する | SAML の一部設定、証明書欄 |
| PEM 全体 | BEGIN / END 行を含める | 証明書ファイル、秘密鍵ファイル |
| PEM 全体の文字列 | BEGIN / END 行を含め、改行を \n として表現する | 環境変数、JSON、YAML の値 |
Kubernetes Secret では base64 と PEM を混同しない
Kubernetes Secret では、マニフェスト上の data フィールドに base64 エンコードした値を入れます。これは PEM の中身が Base64 であることとは別の話です。PEM ファイル全体を Secret に入れる場合は、PEM ファイルの内容をさらに base64 エンコードして格納することになります。
kubectl create secret tls example-tls \
--cert=server.crt \
--key=server.key \
--dry-run=client -o yamlSecret の tls.crt や tls.key は、Kubernetes 上では base64 文字列として保存されます。しかし、Pod にマウントされた後は通常の PEM ファイルとして見えます。つまり、保存形式と利用時の形式を分けて考える必要があります。
秘密鍵を 1 行化するときの注意
証明書と違い、秘密鍵は漏えいした時点で影響が大きくなります。1 行化すると、環境変数、CI/CD の変数、チャット、チケット、ドキュメントへ貼り付けやすくなりますが、それは同時に漏れやすくなるということでもあります。
秘密鍵を扱う場合は、値の整形方法だけではなく、どこに保存するのか、誰が参照できるのか、ログに出ないか、バックアップや監査ログに残らないかを確認します。整形は作業上の都合ですが、秘密鍵管理は設計上の問題です。
まとめ
PEM 形式の証明書や秘密鍵を 1 行に整形する場合は、Base64 本体だけが必要なのか、BEGIN / END 行を含む PEM 全体が必要なのか、PEM 全体をエスケープ済み文字列として渡すのかを先に確認します。
特に SAML、Kubernetes Secret、環境変数では、同じ「1 行化」でも意味が変わります。証明書や秘密鍵は、文字列として整形できればよいものではありません。どの形式で、どの境界に渡し、どこで復元されるのかを意識して扱う必要があります。
書籍
暗号技術入門 第 3 版 秘密の国のアリス
公開鍵暗号、電子署名、証明書など、TLS や内部 PKI の前提になる暗号技術を確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
関連する記事
あわせて読みたい:

