EternalWindows
証明書管理 / 証明書の役割

インターネット上における電子商取引などの普及に伴い、 通信するデータが守秘されているかどうかの重要性が日々高まっています。 このような要望を満たすためには、データが暗号化されており、 さらにそのデータが第三者によって改ざんされてないかを保障する必要がありますが、 これはCSPの章でも取り上げた公開鍵暗号方式を利用することにより解決することができました。 ただし、この暗号方式の1つの特徴である公開鍵の公開において、 その公開鍵が自分の想定する通信相手から送られてきたかどうかを確認できなければ、 本当の意味で安全な通信を行えているとはいえません。 つまり、いくら通信するデータが第三者から守秘されていても、 肝心の通信先が自分の想定しない相手であっては、 暗号化したデータは複合化され、情報は漏洩してしまうことになります。

上記のような問題を解決するべく、通信相手の身元を保証するために登場したのが証明書です。 証明書は自分の身元を記述した情報と公開鍵を含んでおり、 送信側は身元の開示と公開鍵を公開する手段として証明書を通信相手に送信します。 これを受信した側は、証明書に記述される情報が想定する通信相手と一致するかを確認すると共に、 証明書に含まれる公開鍵と対応する秘密鍵を送信側が持っているかどうかを特定します。 この2つ目の点が特に重要であり、証明書自体は誰にでも公開されますから、 証明書だけを受信しては通信相手が正しいかどうかは分からないわけです。 したがって、証明書は署名されたデータに添付された形で送られることになっています。 この署名されたデータというのは、データ本文から生成したハッシュ値を送信側の秘密鍵で暗号化したものであり、 その値は証明書に含まれる公開鍵で復号できるはずです。 後は、この復号した値とデータ本文から生成したハッシュ値を比較し、それが一致していれば、 送信側が証明書に対応する秘密鍵を持っていることを特定できたことになります。

証明書を署名の一環として利用することにより、単にインターネット上での通信のみならず、 各種ファイルにも署名を行うことができるようになります。 次に証明書が使われている身近な例を示します。

証明書の使用例 詳細
通信 webサーバーとの通信に使用するHTTPや、メールを送信する際に使用するSMTPには、 それぞれ、SSLやS/MIMEといったセキュリティ版のプロトコルが存在する。 これらのプロトコルは、証明書を利用しているため、 データの改ざんを特定すると共に通信相手を保障することができる。 証明書を利用した通信は、PKIと呼ばれることもある。
署名 自己解凍型のEXEファイルやMSIファイルでは、 インストールに先立ってファイルの公開元を確認できるように、 署名が行われていることがよくある。 特にネットワーク上からのインストールを想定したClickOnceアプリケーション等では、 そのアプリケーションが想定するサーバーから公開元されたものであるかを確認するために、 署名を行っておくことは重要な意味を持つ。
認証 証明書にはその証明書を所有する個人のデータが含まれていることから、 このデータをユーザー名とパスワードの入力に置き換わる認証メカニズムとして利用できる。 たとえば、スマートカードに証明書を格納して、認証時にカードをセットするような事例がある。 有効期限が経過していたり、認証機関によって失効された証明書は使用されるべきではないため、 この点に注目することでより強固な認証を行うことができる。

上記した例を実現するためには、具体的にどのような実装が必要になるのでしょうか。 たとえば、SSLによる暗号化はSSPIでSCHANNEL_CRED構造体を使用すれば可能ですから、 このAPIに対して証明書を指定するようにし、 完成したデータをWinsockのようなAPIで送信すればよいでしょう。 署名に関してはファイル署名の章でも取り上げるように、CryptUIWizDigitalSignを呼び出すのが簡単です。 スマートカードから証明書を取得したい場合は、CryptGetKeyParamにKP_CERTIFICATEを指定するようにします。 証明書からWindowsの認証情報へマップしたい場合は、PstMapCertificateを呼び出せばよいと思われます。

証明書を使用する例に応じて、使用する証明書の種類も変化することに注意してください。 たとえば、webサーバーを構築してSSL通信を行いたい場合は、 SSLサーバー証明書と呼ばれる証明書が必要であり、 これを発行するCA(証明機関)に対して、証明書申請の手続きを行うことになります。 この手続きについては、予め申請者側で鍵ペアを作成しておき、 その公開鍵と個人データを証明書要求(CSR)として送信する場合もあれば、 CAが提供するサーバー上に所定の情報を入力する場合もあります。 証明書にはいくつかの種類があるため、まずそれらを確認しておきます。

拡張子 説明
.cer 一般的に言われる証明書はこのファイル形式であり、 証明書の所有者情報や公開鍵を含んでいる。 .cerファイルは、.spcファイルや.pfxファイルに含まれることもある。
.spc ソフトウェア発行元証明書とも呼ばれ、 インターネット上で配布するファイルなどに署名を行う際に利用される。 .cerファイルとの違いは、.spcファイルがCAから発行された証明書に加えて、 CA自身の証明書が含まれていることであり、.spcファイル単一で自身が変更されていないかの検証を行える。 CAから.spcファイルを取得する場合は、発行された証明書に関連する秘密鍵を格納した.pvkファイルが提供され、 これら2つを署名ツールに指定することでファイルへの署名を行うことができる。 .spcファイルは、PKCS #7形式でフォーマットされている。
.pfx 秘密鍵と証明書を共に格納できる形式で、ファイルの解読をパスワードで制御できる。 この形式は、証明書と秘密鍵を別コンピュータ上にインポートしたい場合や、 .spcファイルと.pvkファイルを1つのファイルにまとめたい場合に利用される。

証明書の作成を開発者が自ら行わず、 第三者であるCAに作成してもらうという点が重要です。 開発者が自分で証明書を作成するとなると、 その証明書には自分の本来の身元とは異なる情報を格納するようなことが できてしまいますから、その身元を正しく証明するCAというものが必要になるのです。 しかし、この考えでいくと、そのCAが正しいかどうかを証明する また別のCAというものが必要になり、 最終的には自分で自分を証明するCAがどうしても必要です。 このようなCAはルートCAと呼ばれ、 公開されることになる原則全ての証明書は、 ルートCAによって直接、あるいは間接的に証明されていなければなりません。

これはある証明書の「証明のパス」を表示したものですが、 このパスの構造がツリーになっていることに注目してください。 ツリーの一番上の証明書がルートCAの証明書であり、 一番下が現在参照している証明書を表しています。 このツリーの中間に存在するのが通常のCAであり、 一番下の証明書は中間のCAによって証明されていることになります。 そして、中間のCAは信頼できるルートCAによって証明されていますから、 一番下の証明書は信頼できることになります。

証明書がCAによって証明されるとは、 証明書にCAの署名が格納されることを意味します。 つまり、証明書から生成したハッシュ値をCAの秘密鍵で暗号化したものが格納されます。 CAの証明書に含まれる公開鍵でその暗号化された値を復号できた場合、 証明書の署名が正しいことが分かります。

webサーバーとSSL通信を行うような場合、クライアントはサーバーの証明書を受信することになりますが、 この証明書が信頼できるかどうかはどうやって判断すればよいでしょうか。 既に述べてきたように、証明書にはCAの署名が入っており、 その署名を検証すればよいわけですが、これにはCAの証明書が必要になるはずです。 ここで重要なのは、サーバーの証明書が正しいCAに署名をしてもらっていたとしても、 クライアント側がそのCAのことを知らなければその証明書を信頼することができませんから、 多くのコンピュータにはある一群のCAの証明書が既定でインストールされています。 これにより、広く認知されているCAから発行された証明書は、 多くのコンピュータにおいて信頼されることになります。 証明書をインストールするとは、証明書ストアに証明書を格納するということであり、 多くの証明書を証明書ストアで一括管理するのが目的です。

このダイアログは、IEのインターネットオプションのコンテンツなどから表示することができます。 「個人」や「ほかの人」などの個々のタブが証明書ストアを表しており、 その名前によって格納すべき証明書が異なっています。 たとえば、「個人」の証明書ストアには、秘密鍵と対応する公開鍵を持つ証明書が格納され、 秘密鍵はそのコンピュータのCSPにて管理されていることになります。 一般に、開発者がCAより発行してもらった証明書は、この証明書ストアに格納することになるでしょう。 「中間CA」の証明書ストアには、ルートCAでない証明期間の 証明書が格納されています。 発行先というのは、その証明書が誰に対して発行されたのかを示す名前で、 言い換えるなら証明書の所有者ということになります。 一方、発行者というのは、その証明書を発行したCAの名前であり、 ここに記述されるCAの証明書は、 「信頼されたルートCA」の証明書ストアに格納されているはずです。 中間CAを証明するためには、ルートCAの証明書が必要だからです。 ルートCAの証明書は自分で自分を証明するため、 発行先と発行者は同じ名前となります。

証明書ストアには、証明書以外にCTLやCRLというものも格納されています。 その内容や目的は互いに全く異なるものですが、 プログラミングにおいては証明ストアからの取り出し方法など、 似ている部分が数多くあるため、それぞれの型を確認しておきます。

識別するデータ
CERT_CONTEXT 証明書
CTL_CONTEXT CTL
CRL_CONTEXT CRL

本章では、証明書を識別するCERT_CONTEXTを取得する方法について説明します。 また、それと平行して証明書ストアがどのように証明書を管理しているのかと、 証明書に関するダイアログの取り扱いに関しても取り上げます。 証明書を操作する関数の名前はCertで始まることがありますが、 そのような関数もCryptoAPIのカテゴリに入ります。


戻る