主要なデータ形式

X.509、PKCS 7、PKCS 10、PKCS 12、ASN.1、PEMなど、暗号技術と証明書に欠かせない形式を解説します。

主要なデータ形式

X.509

X.509はデジタル証明書のまさに標準です。かつてはOpenPGPのような対抗規格もありましたが、現在ではあまり使われていません。とはいえ、正確にはX.509が正しい標準というわけではありません。X.509は実際にはITU-Tの標準であり、本当に重要な定義はITU-TではなくIETFの標準、すなわちRFC 5280に含まれています。このRFCはX.509に基づく「インターネット向けPKIプロファイル」を定義しており、実務上意味を持つのはこのプロファイルだけです。

デジタル証明書は非対称暗号、とりわけデジタル署名を利用します。今日のデジタル証明書の最も一般的なユースケースはサーバー認証です。誰もがすでに証明書を使ったことがありますが、それがX.509証明書だと意識していない場合がほとんどでしょう。HTTPSのWebサイトにアクセスするたびに、ブラウザーはWebサーバーとのTLS接続を確立します。Webサーバーは自身が何者であるかを証明するためにX.509証明書を使います。たとえば銀行のWebサイトにアクセスして口座から送金するとき、利用者は通信相手が本当に自分の銀行であることを確かめたいはずです。攻撃者は銀行のWebサイトになりすまし、利用者のパスワードとTANを読み取って、自分が管理する口座へ送金しようとするかもしれません。攻撃者は銀行のWebサーバーのX.509証明書を持っていないため、HTTPSはこれを防ぐのに役立ちます。ブラウザーが特定のドメインにHTTPS接続していると表示している場合、証明書によって、そのドメインを所有する者のWebサーバーに本当に接続していることが保証されます。

証明書はどのようにしてそれを実現するのでしょうか。証明書にはいくつかのメタデータ、暗号鍵ペアの公開鍵、そして認証局による署名が含まれます。この3つの部分を順に見ていきましょう。

X.509証明書の内容

メタデータ

X.509証明書のメタデータには、とりわけ、どの期間有効か、証明書を何に使うべきか、誰に対して発行されたかといった情報が含まれます。特にTLSサーバー証明書の場合は、Webサーバーのドメインが含まれます。ブラウザーは、アクセスしようとしたドメインと証明書内のドメインを比較します。一致しない場合、ブラウザーは処理を続行せず、警告を表示します。証明書が期限切れの場合も警告を表示します。

奇妙なことに、TLSのないHTTPサイトにアクセスした場合、ブラウザーは警告を表示しないことが多くありました。こちらのほうがさらに安全性は低いにもかかわらずです。無効なX.509証明書を持つWebサーバーにアクセスした場合、それは単なる設定ミスかもしれず、通信を盗聴する攻撃者からは実際には保護されている可能性があります。一方、HTTP接続はまったく保護を提供しません。

もっとも、この問題については証明書ピン留めなど、改善も進んでいます。ただしこれは高度なテーマなので、X.509証明書に含まれる残り2つの要素を見ていきましょう。

公開鍵

証明書には非対称鍵ペアの公開部分が含まれます。この暗号技術によって、Webサーバー(用途が異なる場合は一般に証明書の保持者)は、鍵ペアの秘密部分も保有していることを、接続してくるクライアントやその他の誰にもそれを明かさずに証明できます。これによりクライアントは、そのWebサーバーが証明書をコピーしただけの者ではなく、本当に証明書の所有者であることを確信できます。実のところ証明書自体のコピーはかなり容易です。Webサーバーは接続を試みるすべての相手に証明書のコピーを送るからです。一方、秘密鍵はWebサーバーから外に出ることがないため、盗み出すのは困難または不可能です。HSMやTPMなど、秘密鍵の窃取をさらに困難にする手段もいくつかあります。

認証局による署名

メタデータにより、クライアントはその証明書が特定の用途に適しているかを確認できます。公開鍵は、通信相手が実際に証明書の所有者であることを示します。しかし攻撃者も、新しい鍵ペアと新しい証明書を作れば、この2つの条件を満たせてしまいます。では、クライアントはその証明書が信頼できるとどうやって判断するのでしょうか。

証明書には、認証局(CA)の証明書に属する別の鍵ペアによる暗号署名が含まれます。CA証明書も同じ方法で検証でき、やはり別の証明書によって署名されています。クライアントはこの「信頼チェーン」を、いわゆるリーフ証明書からルートCA証明書までたどることができます。ルートCA証明書は自己署名されていること、つまり証明書の署名が自身の鍵ペアによるものであることで識別できます。通常この過程は1段階か2段階であり、関与するCA証明書は1つか2つだけです。

認証局は証明書を発行する際に、メタデータが正しいことを慎重に確認しなければなりません。たとえば自社ドメインのTLSサーバー証明書を取得したい場合、自分が本当にそのドメインの所有者であることを認証局に証明する必要があります。この確認がどれだけ厳格かによって、基本的な証明書かExtended Validation(EV)証明書かが決まります。

各ブラウザーとオペレーティングシステムには、あらかじめ定義された信頼されたルートCAの一覧が付属しています。ユーザーや管理者は、信頼されたルートCAを追加できます。特定の用途に限って信頼されるルートCAもあれば、より広範に信頼されるものもあります。クライアントは、信頼チェーンが信頼されたルートCAで終端しているかを確認します。終端しており、信頼チェーン内のすべての証明書がまだ有効で、メタデータがその用途どおりに使われていることを示していれば、Webサーバーのリーフ証明書は信頼され、接続が確立されます。

X.509証明書の有効性

X.509証明書は、確立されるべき信頼がすべてです。すでに述べたとおり、信頼の判断基準の1つは、証明書が信頼されたルートCAまでチェーンでつながっていることです。もう1つは、有効期間内であることです。これは通常、期限切れでないことを意味しますが、多くは技術的な誤りによって、証明書がまだ有効になっていない場合もあります。そしてもう1つ基準があります。証明書を発行した認証局がそれを失効させていないことです。これはそれ自体で1つのテーマになるため、別の記事で解説しています。

PKCS#7

PKCS#7は暗号データ形式における万能ナイフのような存在で、暗号化されたメッセージ、署名されたメッセージ、署名および暗号化されたメッセージ、証明書、秘密鍵など、事実上あらゆるものを格納できます。

これはこの形式の大きな欠点でもあります。アプリケーションやユーザーがPKCS#7を受け取っても、それをどう扱えばよいかはそれだけでは分かりません。重要なユースケースをいくつか挙げます。

  • S/MIMEメッセージは、基本的にPKCS#7を本文または添付ファイルとする電子メールです。
  • SCEPのリクエストとレスポンスは、いずれも実際にはPKCS#7の署名付きメッセージです。
  • ESTのレスポンスはCMSメッセージです。

エンコード

一般的なファイル拡張子は、.p7b(DERエンコード)、.p7s(署名付きメッセージまたはメッセージ署名)、.p7m(署名または暗号化されたメッセージ)です。ラベル「PKCS7」を用いたPEMエンコードも定義されていますが、ほとんど使われません。

ツール

WindowsではPKCS#7メッセージをダブルクリックで開くことができ、暗号シェル拡張が内容を表示します。ただし通常取り出せるのは証明書とその秘密鍵だけで、メッセージの内容は取り出せません。

OpenSSLなどのツールを使えば、これらのファイルを別の形式に変換できます。

PKCS#10

PKCS#10で定義される証明書署名要求(CSR)は、認証局(CA)から取得したい証明書の内容を記述したファイルです。X.509証明書に似た構造を持ちますが、認証局による署名がありません。代わりに証明書要求者の署名が含まれます。とはいえ形式は異なるため、自己署名証明書と同じものではありません。

バイナリのDERエンコードにすることも、「CERTIFICATE REQUEST」ラベルを用いてPEMエンコードにすることもできます。

PKCS#12

PKCS#12は、特にWindows環境ではPFXとしても知られています。そのため一般的なファイル拡張子は.pfxと.p12です。X.509証明書と、技術的に強制されているわけではないものの、ほぼ必ず対応する秘密鍵を格納します。

PKCS#12ファイル内のデータは通常、パスワードで暗号化されます。多くの場合、暗号化されるのは秘密鍵だけなので、アプリケーションが対応していればパスワードを知らなくても証明書を取り出せます(ただし多くのアプリケーションは対応していません)。Windows環境では証明書とその秘密鍵をファイルに保存する方法としてPKCS#12が最も一般的ですが、Linux環境ではPEMエンコードされたPKCS#8ファイルのほうが一般的です。

この標準は、入れ子になった「safebag」に証明書と秘密鍵を格納する方法を数多く用意しているため、PKCS#12ファイルには次のような互換性の問題があります。

  • Windowsは、PKCS#12内の秘密鍵を、本来対応する1つの証明書だけでなく、そのファイルから取り出したすべての証明書に関連付けることで知られています。PKCS#12に証明書チェーンが含まれている場合、WindowsはCA証明書の秘密鍵を保持していると表示することがあります。
  • macOSでは、暗号アルゴリズムが新しすぎるとPKCS#12ファイルをインポートできません。
  • 受け取り側のアプリケーションが証明書を取り出せるようにするため、PKCS#12ファイル内の証明書を暗号化する必要がある場合があります。ただし、非常に古く脆弱なアルゴリズムにしか対応していないものもあります。情報自体はいずれにせよ公開されるものなので、通常これは問題になりません。しかしOpenSSL 3.xはこうした古く脆弱なアルゴリズムをサポートしておらず、そのPKCS#12を開くことを拒否します。

ASN.1とPEM

Abstract Syntax Notation One(ASN.1)は、データ構造を記述するための言語です。整数やシーケンスといった定義済みの基本データ型があり、プロトコルやファイル形式の設計者は、それらを使って独自のデータ型を定義できます。

DERエンコード

ITU-T標準X.680は、ASN.1で規定されたデータに対する複数のエンコード方式を定義しています。X.509関連のデータで最も重要なエンコードはDERです。型のエンコード方法が一通りしかないため、型のバイナリDER表現のハッシュは常に同じ値になるからです。これは、たとえばASN.1でエンコードされたデータに署名する際に重要になります。

PEMエンコード

X.509関連のファイル形式の多くは、すべてではありませんが、DERエンコードでバイナリとして保存することも、DERエンコードの上にさらにPEMエンコードを適用することもできます。PEMはASCII文字だけを使うため、クリップボードで簡単にコピー&ペーストでき、数十年前にまだそれが重要だった頃には電子メールで送ることもできました。

ツール

ASN.1でエンコードされたファイルがあり、その型が分からない場合や、その型を扱えるアプリケーションがない場合でも、生のASN.1構造をデコードして中身を確認できます。Windowsでは、組み込みツールのcertutilがcertutil -decodeコマンドでこれを行えます。