[6] .pem
は、証明書や秘密鍵などの暗号化に関わるファイルの交換・保存用のデータ形式です。
[43] 証明書ダウンロード仕様書 >>42 は証明書や証明書鎖に関する
.pem
ファイル形式を定義しています。
[7] それ以外の .pem
ファイル形式一般を規定した仕様書は長年存在していませんでしたが、
2015年に RFC 7468 として IETF で標準化されました。
[11] .pem
形式のファイルは、 ASCII 文字列で構成されるテキストファイルです。
[13] .pem
形式のファイルは、1つ以上のメッセージで構成されます >>59。
[62] メッセージの前に他のデータがあっても構わず、構文解析器は無視しなければなりません >>59。 仕様書ではその意味は規定されていませんが、 補足説明などを入れるために使われているようです。
[92] メッセージは複数あり得るので、その前に挿入できるということは、 実質上メッセージとメッセージの間に挿入できるということです。 しかし最後のメッセージの後には挿入できません。
[15] メッセージは、 pre-EB、データ、 post-EB で構成されます。
[16] pre-EB は -----BEGIN
の後にメッセージ種別が入り、
-----
が続きます >>59。最後に改行が入ります。
[17] post-EB は -----END
の後にメッセージ種別が入り、
-----
が続きます >>59。最後に改行が入ります。
[64] pre-EB と post-EB のメッセージ種別は同じでなければなりません >>59。実装は違っていてもエラーとせず無視して構いません >>59。
[20] データは、オクテット列を Base64 で符号化したものです。 PEM 版 Base64 >>21 は1行を丁度64文字とすることを求めています。 RFC 7468 も64文字丁度の RFC 4648 Base64 としなければならないと規定しています >>59。 構文解析器は他の文字数でも扱えて構いません >>59。
[78] RFC 7468 の ABNF 構文は詰めの省略を認めていますが、 その意味と処理方法は説明されていません。 RFC 7468 の参照する RFC 4648 によると原則として詰めの省略は禁止されており、矛盾しています。
[63] 構文解析器は、空白その他 Base64 以外の文字を無視するべきです。 行末の空白は、無視する実装が多いようです。 Base64 の行頭や行内の空白は、 扱えない実装が多いようです。余分な空白を生成してはなりません。 >>59
[24] 改行は、 CR
、LF
、
CR
LF
のいずれかによって表されます >>59。
[25]
OpenSSH は少なくても秘密鍵 (OPENSSH PRIVATE KEY
)
の扱いに関してかなり厳しく、 CR
が入っているとエラーにします。
LF
のみである必要があります。
[37] PEM は RFC 4716 のファイル形式と似ていますが、微妙に違います。
[38] OpenPGP の ASCII Armor とも似ていますが、そちらは元の PEM の形式により似ています (微妙に違います)。
[40] SSH クライアントはこれらのいずれとも微妙に違った、本項の PEM 形式に RFC 822 風ヘッダーを足した秘密鍵ファイル >>58 を使うことがあります。 (本項の形式を使うこともあります。) RFC 4716 は SSH 用として更に微妙に異なる構文を規定しています。
[97] SSH 用のファイル形式もまた PEM 形式と呼ばれているようです。 ややこしいことに SSH が使うファイル形式も実装の世代によって メッセージ種別 (やそれによって表される内容) の違いがあって互換性の問題が生じていて、 (新旧どちらも「PEM 形式」であるにも関わらず) 一方が 「PEM形式」と呼ばれることがあるようです。
[98] SSH 用ファイル形式は RFC 822 ヘッダーが1個もないと、 通常の PEM 形式になります。
[77] これらのファイル形式は、おそらくは大元は共通なのでしょうが、 他のファイル形式を参考に自身の用途に移植して実装した時に、 それぞれの思惑で少しずつ違いが生じたのでしょう。
[99] まあそもそもどのファイル形式も本家の PEM とは関係ないので、 どれを PEM と呼んでも別にいい (どれも等しく俗称) だったのでしょう。
[39] 類似ファイル形式 (元の PEM, >>37, >>38, >>40) で使われるメッセージ種別相当の文字列には次のものがあります。
[52] .pem
ファイルとして構文解析して Base64 符号化されたバイナリーデータを取り出した後の処理方法は、
利用する場面によって異なります。
[54] .pem
ファイルの内容が意図したものと異なる場合もあります。
EB の記述が想定と異なる場合もありますし、 EB の記述と実際の内容が異なる場合もあります。
.pem
ファイルを送信したプロトコルにおける MIME型と内容が異なる場合もあります。
[66] EB の記述と実際の内容が異なる場合でも、構文解析器は華麗に処理できなければなりません。実際の内容に従い処理しても構いませんが、 セキュリティー上問題ないか注意する必要があります。既存の実装がどう処理するかは、 それぞれです。 >>59
[41] MIME型としては application/x-pem-file
が使われます。
[55] 内容により異なる MIME型が使われることもあります。
application/pem-certificate-chain
[34] 内容により .cer
、.csr
、.key
などが用いられることもあります
(それぞれ証明書、CSR、鍵)。
これらは .pem
形式でない元のバイナリーファイルでも使われることがあり、
拡張子だけではファイル形式を判定できません。
CERTIFICATE
[67] ラベル CERTIFICATE
は、公開鍵証明書に用いられます
>>59。
[68] データは、 ASN.1 Certificate
です。
BER でなければなりません。 DER
が非常に好ましいです。 >>59
[69] 実際には X.509 証明書の他に、
PKCS #7証明書鎖 >>42, >>29 や
Netscape Certificate Sequence >>42
にもラベル CERTIFICATE
が使われることがあります。
[70] また X.509 証明書を表すためにラベルとして X509 CERTIFICATE
や X.509 CERTIFICATE
が使われることがあります >>59。
これらを生成してはなりませんが、構文解析器は等価として扱うべきです
>>59。
[71] メッセージの前後に説明文が記述されることがあります。 その場合は証明書を説明するものであるべきです。 >>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
が使われることもよくあります。
[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 と呼んでいたのかもしれません。
[50] 本ファイル形式を明確に規定する仕様書として現時点で唯一発見できているのが、 証明書ダウンロードです。
[46] 証明書ダウンロード仕様書 >>42 の最も初期と思われる1996年版 >>45 の定義は、 PEM という語は登場しませんが、当時の PEM の RFC である RFC 1113 の Base64 >>47 を参照しています。
[22] PEM 版 Base64 は、 RFC 1421 >>21 が最新の定義です。 (ただしこの RFC は既に HISTORIC となっています。)
[87]
に発行された IETF 提案標準
RFC 4945
には、 .pem
ファイルの構文が (曖昧ながら) 定められていました。
>>86
[61]
2015年に RFC 7468 が IETF 提案標準 RFC
として発行され >>60、 .pem
ファイル一般の構文が初めて明文化されました。
[88] 先行仕様の RFC 4945 にはなぜか一言も言及がありません。 明らかに重複しており、更新なりなんなり手続きが必要だったはずです。 RFC 4945 で仕様が明文化されていたことは世間ではあまり知られていませんでした。 まさか IETF でも知る人ぞ知る状態だったのでしょうか。
[82]
PEMファイルは、証明書や 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
[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
[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
[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