web-dev-qa-db-ja.com

PEMファイル形式はどこに指定されていますか?

.PEMファイルを解析する必要があります。
「プライバシーが強化された電子メール」の標準がRFC 1421-24で定義されていることを知っています。しかし、彼らは私がOpenSSL .pemファイル内で見つけたいくつかのテキストに言及していないようです(たとえば、「キー属性」、「BEGIN CERTIFICATE」など...)これはOpenSSL固有の形式ですか?

49
hopia

長い間、情報の暗号化交換に関するPEM形式の正式な仕様はありませんでした。 PEMはテキストエンコードですが、実際にエンコードされる内容はコンテキストによって異なります。 2015年4月、IETFは RFC 7468 を承認しました。これにより、さまざまな実装がPEMテキストエンコーディングを使用してデータを交換する方法が最終的に文書化されます。次のリストは、RFCから直接引用したもので、次のシナリオで使用されるPEM形式を説明しています。

  1. 証明書、証明書失効リスト(CRL)、およびインターネットX.509公開鍵インフラストラクチャ証明書および証明書失効リスト(CRL)プロファイルのサブジェクト公開鍵情報構造 [RFC5280]
  2. PKCS#10:証明書要求の構文 [RFC2986]
  3. PKCS#7:暗号メッセージ構文 [RFC2315]
  4. 暗号化メッセージの構文 [RFC5652]
  5. PKCS#8:秘密鍵情報構文 [RFC5208] 、非対称鍵パッケージで1つの非対称鍵に名前変更 [RFC5958] 、および同じ暗号化された秘密鍵情報構文ドキュメント。
  6. 承認のためのインターネット属性証明書プロファイルの属性証明書 [RFC5755]

このRFCによると、上記のシナリオでは、次のラベルが[〜#〜] begin [〜#〜]ヘッダー内にあり、 [〜#〜] end [〜#〜]フッター。 RFCの図4には、対応するASN.1タイプを含む、より詳細があります。

しかし、それだけでは十分ではありません。 RFCは、既存の実装を調べ、それらが何をしたかを文書化することによって作成されました。 RFCは最初に作成されたわけではなく、既存の信頼できるドキュメントに基づいて作成されたものでもありません。したがって、一部の実装と相互運用したい場合は、実装のソースコードを調べて、それらがサポートしているものを理解する必要があります。

たとえば、OpenSSLはこれらのBEGINおよびENDマーカーを crypto/pem/pem.h で定義します。以下は、サポートするすべてのBEGINおよびENDラベルを含むヘッダーファイルからの抜粋です。

# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
# define PEM_STRING_X509         "CERTIFICATE"
# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
# define PEM_STRING_X509_CRL     "X509 CRL"
# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
# define PEM_STRING_PUBLIC       "PUBLIC KEY"
# define PEM_STRING_RSA          "RSA PRIVATE KEY"
# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
# define PEM_STRING_DSA          "DSA PRIVATE KEY"
# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
# define PEM_STRING_PKCS7        "PKCS7"
# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS   "PARAMETERS"
# define PEM_STRING_CMS          "CMS"

これらのラベルは出発点ですが、実装がラベル間のデータをどのようにエンコードするかを調べる必要があります。すべてに対して正しい答えは1つではありません。

24
indiv

2015年の更新された回答:モデレーター@royhowieが回答を削除する前に、ユーザーはすでに2回回答したため、現在 RFC 7468が定義されていますPEMヘッダー 。次の引用はほんの一部であり、実際の仕様を読む必要があります。実際の仕様は、StackOverflowよりもずっと長くインターネットに留まる可能性があります。

ただし、@ royhowieは、テキストがない限り、「リンクのみ」としてRFCを指すすべての回答を削除します。だからここにいくつかのテキストがあります:

  1. PKCS#10認証要求構文のテキストエンコーディング

    PKCS#10証明書リクエストは、「CERTIFICATE REQUEST」ラベルを使用してエンコードされます。エンコードされたデータは、[RFC2986]で説明されているように、BER(DERを強く推奨。付録Bを参照)エンコードされたASN.1 CertificationRequest構造である必要があります。

-----証明書リクエストの開始-----

MIIBWDCCAQcCAQAwTjELMAkGA1UEBhMCU0UxJzAlBgNVBAoTHlNp​​bW9uIEpvc2Vm c3NvbiBEYXRha29uc3VsdCBBQjEWMBQGA1UEAxMNam9zZWZzc29uLm9yZzBOMBAG ByqGSM49AgEGBSuBBAAhAzoABLLPSkuXY0l66MbxVJ3Mot5FCFuqQfn6dTs + 9/CM EOlSwVej77tj56kj9R/j9Q + LfysX8FO9I5p3oGIwYAYJKoZIhvcNAQkOMVMwUTAY BgNVHREEETAPgg1qb3NlZnNzb24ub3JnMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwegADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgM/ADA8 AhxBvfhxPFfbBbsE1NoFmCUczOFApEuQVUw3ZP69AhwWXk3dgSUsKnuwL5g/ftAY dEQc8B8jAcnuOrfU

-----証明書リクエストの終了-----

図9:PKCS#10の例

「NEW CERTIFICATE REQUEST」のラベルも広く使用されています。このドキュメントに準拠するジェネレータは、「証明書要求」ラベルを生成する必要があります。パーサーは「NEW CERTIFICATE REQUEST」を「CERTIFICATE REQUEST」と同等のものとして扱うことができます。

20
mikemaccana

あなたが始めるために:私の知る限り、人間が読める(単語やものがある)部分がある場合、それは人間のオペレーターが問題の認証が何であるか、有効期限などを簡単に手動で確認できることを意味します。だからあなたはそれを無視することができます。

BEGIN-ENDブロックの間にあるものを解析する必要があります。

内部には、Base64でバイトにデコードする必要があるBase64でエンコードされたエンティティがあります。これらのバイトは、DERエンコードされた証明書/キー/などを表します。 DERデータの解析に使用できる優れたライブラリーはわかりません。

各ブロック内のデータを理解するためのテストとして、BEGIN-ENDブロックの間にあるものを、JavaScriptでASN.1デコードを行うこのサイトに貼り付けることができます。

http://lapo.it/asn1js/

私は本番環境の秘密鍵をどのサイトにも貼り付けません(ただし、それは単なるJavaScriptのようです)。

Base64: http://en.wikipedia.org/wiki/Base64

DER: http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules

ASN.1: http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

13
Sami Koivu

この問題に関して 古いスレッド を見つけました。カプセル化の境界には「公式の」標準形式がないようで、これを判断する最良の方法は、BEGINステートメントで見つけた既知のキーワードに基づいて内容を推測することです。

Indivが回答したように、キーワードの完全なリストについては、OpenSSL crypto/pem/pem.hヘッダーファイルを参照してください。

8
hopia

OpenSSLに固有のものかどうかはわかりませんが、 PEM暗号化形式 のドキュメントがあなたの探しているものかもしれません。

2
jathanism

PEMファイル形式はどこに指定されていますか?

一つの場所はありません。規格によります。独自のカプセル化境界を作成して、独自のソフトウェアで使用することもできます。

@indivが述べたように、OpenSSLは<openssl dir>/crypto/pem/pem.hにかなり包括的なリストがあります。

誰かがPKIXワーキンググループに、2006年に求めているようなリストを提供するように依頼しました。ワーキンググループは辞退しました。 PEMファイル形式のrfcドラフト要求 を参照してください。

0
jww