RFC 7468

PEM (ファイル形式)

[6] .pem は、証明書秘密鍵などの暗号化に関わるファイルの交換・保存用のデータ形式です。

仕様書

[43] 証明書ダウンロード仕様書 >>42証明書証明書鎖に関する .pem ファイル形式を定義しています。

[7] それ以外の .pem ファイル形式一般を規定した仕様書は長年存在していませんでしたが、 2015年に RFC 7468 として IETF で標準化されました。

[44] 歴史の項も参照。

構文

[11] .pem 形式のファイルは、 ASCII 文字列で構成されるテキストファイルです。

[12] 非ASCII文字が含まれる場合にどう解釈されるかは定かではありません。
[74] report-uri で指定された URL に送信される JSON では、 .pem 形式の文字列が使われます。

[13] .pem 形式のファイルは、1つ以上のメッセージで構成されます >>59

  1. +
    1. ?
      1. 前書き
    2. メッセージ
[14] 多くの場合はメッセージは1つだけですが、 certification path を表す一連の証明書を表す場合、 ルート証明書として使われる証明書群を表す場合、 秘密鍵証明書を含めた場合、 その他用途次第で複数のメッセージが含まれることがあります。 複数含まれる場合、用途により、順序が指定されることがあります。 例えば中間証明書ルート証明書末端実体証明書に近い順序に並べる必要があるかもしれません ( 証明書鎖 )。

[62] メッセージの前に他のデータがあっても構わず、構文解析器は無視しなければなりません >>59仕様書ではその意味は規定されていませんが、 補足説明などを入れるために使われているようです。

[92] メッセージは複数あり得るので、その前に挿入できるということは、 実質上メッセージメッセージの間に挿入できるということです。 しかし最後のメッセージの後には挿入できません。


[15] メッセージは、 pre-EB、データ、 post-EB で構成されます。

  1. pre-EB
  2. データ
  3. post-EB
[31] OpenSSLEB を header line、footer line とそれぞれ呼んでいるようです。
[51] pre-EB の前や post-EB の後に何らかのデータがあっても、無視します >>42

[16] pre-EB-----BEGIN の後にメッセージ種別が入り、 ----- が続きます >>59。最後に改行が入ります。

  1. -----BEGIN
  2. メッセージ種別
  3. -----
  4. 改行

[17] post-EB-----END の後にメッセージ種別が入り、 ----- が続きます >>59。最後に改行が入ります。

  1. -----END
  2. メッセージ種別
  3. -----
  4. 改行
[27] BEGINEND の後には U+0020 が入ります。

[64] pre-EBpost-EBメッセージ種別は同じでなければなりません >>59。実装は違っていてもエラーとせず無視して構いません >>59

[65] 異なっていても扱える実装と、扱えない実装があります >>59
[18] 最後のメッセージの後には改行があるべきです >>59

[20] データは、オクテット列Base64符号化したものです。 PEMBase64 >>21 は1行を丁度64文字とすることを求めています。 RFC 7468 も64文字丁度の RFC 4648 Base64 としなければならないと規定しています >>59。 構文解析器は他の文字数でも扱えて構いません >>59

[19] 最後の行は、64文字以下で構いません >>59
[23] すべての .pem ファイルがこれに従っているかは定かではありません。
[28] 元々の PEM の暗号化メールでは、データの部分は RFC 822 風のヘッダー空行本体で構成されるメッセージで、 Base64 はそのうちの本体の部分だけでした。

[78] RFC 7468ABNF 構文は詰めの省略を認めていますが、 その意味と処理方法は説明されていません。 RFC 7468 の参照する RFC 4648 によると原則として詰めの省略は禁止されており、矛盾しています。

Base64 も参照。

[63] 構文解析器は、空白その他 Base64 以外の文字を無視するべきです。 行末の空白は、無視する実装が多いようです。 Base64 の行頭や行内の空白は、 扱えない実装が多いようです。余分な空白を生成してはなりません>>59

[24] 改行は、 CRLFCRLF のいずれかによって表されます >>59

[25] OpenSSH は少なくても秘密鍵 (OPENSSH PRIVATE KEY) の扱いに関してかなり厳しく、 CR が入っているとエラーにします。 LF のみである必要があります。

  1. |
    1. CR
    2. LF
    3. CRLF
[32] 構文的に正しくないファイルを与えられた時どう解釈するのかは定かではありません。

メッセージ種別

[26] メッセージ種別 (RFC 7468 のいうラベル (label) ) には、次のものがあります。

類似ファイル形式

[37] PEMRFC 4716 のファイル形式と似ていますが、微妙に違います。

[38] OpenPGPASCII Armor とも似ていますが、そちらは元の PEM の形式により似ています (微妙に違います)。

[40] SSH クライアントはこれらのいずれとも微妙に違った、本項の PEM 形式に RFC 822 風ヘッダーを足した秘密鍵ファイル >>58 を使うことがあります。 (本項の形式を使うこともあります。) RFC 4716SSH 用として更に微妙に異なる構文を規定しています。

[97] SSH 用のファイル形式もまた PEM 形式と呼ばれているようです。 ややこしいことに SSH が使うファイル形式も実装の世代によって メッセージ種別 (やそれによって表される内容) の違いがあって互換性の問題が生じていて、 (新旧どちらも「PEM 形式」であるにも関わらず) 一方が 「PEM形式」と呼ばれることがあるようです。

[98] SSH 用ファイル形式は RFC 822 ヘッダーが1個もないと、 通常の PEM 形式になります。

[77] これらのファイル形式は、おそらくは大元は共通なのでしょうが、 他のファイル形式を参考に自身の用途に移植して実装した時に、 それぞれの思惑で少しずつ違いが生じたのでしょう。

[99] まあそもそもどのファイル形式も本家の PEM とは関係ないので、 どれを PEM と呼んでも別にいい (どれも等しく俗称) だったのでしょう。

[100] すると混乱極まった後に遅れて一部の形式だけを標準化する RFC を出した IETF は混乱をややこしくする形で固定化してしまったわけです。 俗称の一部分にだけお墨付きを出して残りは放置なのですから。

[39] 類似ファイル形式 (元の PEM, >>37, >>38, >>40) で使われるメッセージ種別相当の文字列には次のものがあります。

[101] 狭義 PEM で使われるものと共通しているものもいくつかあります。 「どちらの形式でも使われる」 というよりは、 元々広義 PEM で使われていたのが狭義 PEM とそれ以外とで分断された見え方に (今では) なっているというだけのことなのでしょう。
[96] ssh-keygen が生成する秘密鍵PEM 形式ないしそれに類似する形式ですが、 公開鍵はまた別の形式です。

処理

[52] .pem ファイルとして構文解析して Base64 符号化されたバイナリーデータを取り出した後の処理方法は、 利用する場面によって異なります。

[54] .pem ファイルの内容が意図したものと異なる場合もあります。 EB の記述が想定と異なる場合もありますし、 EB の記述と実際の内容が異なる場合もあります。 .pem ファイルを送信したプロトコルにおける MIME型と内容が異なる場合もあります。

[66] EB の記述と実際の内容が異なる場合でも、構文解析器は華麗 (gracefully) に処理できなければなりません。実際の内容に従い処理しても構いませんが、 セキュリティー上問題ないか注意する必要があります。既存の実装がどう処理するかは、 それぞれです。 >>59

[53] Webブラウザーダウンロードした場合の処理は、証明書ダウンロードを参照。

MIME 型

[41] MIME型としては application/x-pem-file が使われます。

[55] 内容により異なる MIME型が使われることもあります。 証明書ダウンロード, application/pem-certificate-chain

[56] 意味的には +pem としても良さそうなものですが ( 構造化構文接尾辞 )、 実際には使われていないようです。

拡張子

[33] 一般には拡張子 .pem が使われます。

[34] 内容により .cer.csr.key などが用いられることもあります (それぞれ証明書CSR)。 これらは .pem 形式でない元のバイナリーファイルでも使われることがあり、 拡張子だけではファイル形式を判定できません。

メッセージ種別 CERTIFICATE

[67] ラベル CERTIFICATE は、公開鍵証明書に用いられます >>59

[68] データは、 ASN.1 Certificate です。 BER でなければなりませんDER非常に好ましい (strongly preferred) です。 >>59

[69] 実際には X.509 証明書の他に、 PKCS #7証明書鎖 >>42, >>29Netscape Certificate Sequence >>42 にもラベル CERTIFICATE が使われることがあります。

[70] また X.509 証明書を表すためにラベルとして X509 CERTIFICATEX.509 CERTIFICATE が使われることがあります >>59。 これらを生成してはなりませんが、構文解析器は等価として扱うべきです >>59

[71] メッセージの前後に説明文が記述されることがあります。 その場合は証明書を説明するものであるべきです。 >>59

[72] >>59

Subject: CN=Atlantis
Issuer: CN=Atlantis
Validity: from 7/9/2012 3:10:38 AM UTC to 7/9/2013 3:10:37 AM UTC
-----BEGIN CERTIFICATE-----
...

[73] 拡張子として .cer を使うこともありますが、 DER 形式と区別するため .crt を使うべきです >>59。 実際には .pem が使われることもよくあります。

[91] CAfileCApath で使われます。

[93] x5uで指定された証明書鎖で使われます。

実装

[83] PKI の実装のほとんどが、何らかの形で対応しています。

[84] OpenSSL はもちろん対応しています。 openssl のサブコマンドのほとんどが、 PEMファイルの入出力に対応しています。 (DER など他の形式にも対応しています。)

文脈

[104] MySQL プロトコルの caching_sha2_password 用の公開鍵応答では、 PUBLIC KEY.pem ファイルが返されます。

歴史

[8] 本ファイル形式名の PEM電子メールにおける暗号化の仕様を指すとされていますが、 PEM に (少なくても RFC として出版されたものには) 本ファイル形式の規定はなく、なぜ .pem ファイルと呼ばれているかは定かではありません。 本ファイル形式は PEM の影響を受けているようですが、 PEM で規定されるメッセージ形式とは明らかに違いがあります。

[9] PEM の実装が使っていたファイル形式なのかもしれません。あるいは PEM の記憶が濃い時代に PEM 風のファイル形式として名付けられたのかもしれません。 (現在でいう) Base64 のことを PEM と呼んでいたのかもしれません。

[10] MIME の一機能に過ぎない Base64 のことを「MIME」と呼ぶ風習がかつて一部にありました。 MIME より前の時代に Base64 のことを「PEM」と呼んでいても不思議ではありません。

[50] 本ファイル形式を明確に規定する仕様書として現時点で唯一発見できているのが、 証明書ダウンロードです。

[46] 証明書ダウンロード仕様書 >>42 の最も初期と思われる1996年版 >>45 の定義は、 PEM という語は登場しませんが、当時の PEMRFC である RFC 1113Base64 >>47 を参照しています。

[48] ちなみに Base64 という名称も PEMRFC には登場していません。 RFC としての初出は MIME ですが、それ以前から Base64 という呼称があったのかは不明です。 いずれにしても1996年には既に MIMEBase64 は有名になっていました。 Base64 と呼びつつも PEMRFC を参照しているのは興味深いところです。
[49] 証明書ダウンロード仕様書が最初の定義で Netscape 社が本形式を考案したのか、 より以前からあった形式を Netscape が実装したのかは不明です。

[22] PEMBase64 は、 RFC 1421 >>21 が最新の定義です。 (ただしこの RFC は既に HISTORIC となっています。)

[87] に発行された IETF 提案標準 RFC 4945 には、 .pem ファイルの構文が (曖昧ながら) 定められていました。 >>86

[61] 2015年RFC 7468IETF 提案標準 RFC として発行され >>60.pem ファイル一般の構文が初めて明文化されました。

[88] 先行仕様の RFC 4945 にはなぜか一言も言及がありません。 明らかに重複しており、更新なりなんなり手続きが必要だったはずです。 RFC 4945 で仕様が明文化されていたことは世間ではあまり知られていませんでした。 まさか IETF でも知る人ぞ知る状態だったのでしょうか。

メモ

[82] PEMファイルは、証明書PKI を使う、あらゆる応用に使われます。 例えば次のようなものがあります。 証明書PKI

[85] PEMファイルといっても中身にいろいろな種類があるし、 使いみちもいろいろあるので、 何でも出来ちゃうすごいもののように聞こえて、 とっつきにくくみえますね。

暗号化

[1] 証明書のファイル形式について () http://moca.wide.ad.jp/moca_guide/about_fileformat.html

[2] .PEM SSL サーバ証明書とは。 ( 版) http://www.digicert.ne.jp/howto/basis/pem-ssl-creation.html

[3] SSL/TLS/PKI メモ (Masatoshi Sato 著, 版) http://siisise.net/linux/ssl.html

[4] RFC 5958 - Asymmetric Key Packages ( 版) https://tools.ietf.org/html/rfc5958#section-5

.p8 files are sometimes PEM-encoded. When .p8 files are PEM encoded

they use the .pem file extension. PEM encoding is either the Base64

encoding, from Section 4 of [RFC4648], of the DER-encoded

EncryptedPrivateKeyInfo sandwiched between:

-----BEGIN ENCRYPTED PRIVATE KEY-----

-----END ENCRYPTED PRIVATE KEY-----

or the Base64 encoding, see Section 4 of [RFC4648], of the DER-

encoded PrivateKeyInfo sandwiched between:

-----BEGIN PRIVATE KEY-----

-----END PRIVATE KEY-----

[5] java - what is the differences between "BEGIN RSA PRIVATE KEY" and "BEGIN PRIVATE KEY" - Stack Overflow ( 版) http://stackoverflow.com/questions/20065304/what-is-the-differences-between-begin-rsa-private-key-and-begin-private-key

[30] rsa - RSA key processing tool ( 版) https://www.openssl.org/docs/apps/rsa.html

[35] dsa - DSA key processing ( 版) https://www.openssl.org/docs/apps/dsa.html

[29] pkcs7 - PKCS#7 utility ( 版) https://www.openssl.org/docs/apps/pkcs7.html

[57] SSL_CTX_load_verify_locations - set default locations for trusted CA certificates ( 版) https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html

Before, between, and after the certificates text is allowed which can be used e.g. for descriptions of the certificates.

[58] PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ, PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW, PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL, PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7, PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE - PEM routines ( 版) https://www.openssl.org/docs/crypto/pem.html

[75] OpenSSL (OpenSSL Foundation, Inc. 著, 版) https://www.openssl.org/docs/manmaster/apps/ecparam.html

[76] OpenSSL (OpenSSL Foundation, Inc. 著, 版) https://www.openssl.org/docs/manmaster/apps/dhparam.html

[79] X.509 Style Guide () https://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt

[80] /docs/manmaster/man3/SSL_CTX_load_verify_locations.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html

[81] /docs/manmaster/man3/SSL_CTX_load_verify_locations.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html

The file can contain several CA certificates identified by

-----BEGIN CERTIFICATE-----

... (CA certificate in base64 encoding) ...

-----END CERTIFICATE-----

sequences. Before, between, and after the certificates text is allowed which can be used e.g. for descriptions of the certificates.

[89] /docs/man1.1.1/man3/SSL_CTX_load_verify_locations.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_load_verify_locations.html

[90] /docs/manmaster/man3/SSL_CTX_load_verify_locations.html (OpenSSL Foundation, Inc.著, ) https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html

[103] The OpenSSH Private Key Format, AJ ONeal, , https://coolaj86.com/articles/the-openssh-private-key-format/

[102] OpenSSH/OpenSSL 鍵データ相互変換 - Qiita, https://qiita.com/angel_p_57/items/6e826105d50cbb0e0abe