公開鍵証明書

2008年03月22日

公開鍵証明書

純粋な公開鍵は単なる数百ビットのバイナリデータです。公開鍵だけが流通してもそれが本当に意図した相手のものであることを保障できませんし、そもそも流通過程で破損したり、出鱈目に作り出されたものでないことを保障できません。

公開鍵証明書 (Public Key Certificate) は公開鍵のバイナリが正しいことを保障し、それを作成した主体 (個人、団体など) の身元を証明するために CA (Certification Authority; 認証局) によって発行された電子証明書です。通常公開鍵はこの公開鍵証明書と一緒に配布されます。

公開鍵証明書の発行

証明書には相手の身元情報や、公開鍵と合わせた電子署名、発行元の CA 情報などが含まれています。クライアントは、自分が持っている (信頼している) CA の公開鍵を使って証明書の電子署名を検証します。もし署名が正しければ、証明書の記載内容と公開鍵が CA に提出されたものと同じであることが保障でき、それは CA によって相手の身元が証明されたことを意味します。

もちろん相手の身元が証明されたとしても、それが自分の意図した通信相手かどうかを確認しなければならないのはユーザの責任です。

証明書チェーン

信頼関係の構造

CA の正当性は CA によって証明されます。自分の正当性を自分で証明している CA を ルート CA と呼び、別の CA によって証明されているものを中間 CA と呼びます。

CA B が CA A の秘密鍵によって署名された公開鍵証明書を持っている時、A は B の正当性を証明していることになります。この構造により、ルート CA を頂点とする CA のツリーが形成されます。

ある証明書 (破損や失効をしていない) が信頼できるかどうかは以下の 2 点に基づいて再帰的に決定されます。

  1. 信頼している CA によって発行された証明書は信頼できる。
  2. 信頼している CA が信頼している CA は信頼できる。

ある証明書に対して、その証明書自身、その証明書を発行した CA の証明書、その CA の正当性を証明した CA の証明書、…という具合にルート CA の証明書まで遡った一連の証明書セットを証明書チェーンと呼びます。そして証明書が信頼できるかどうかは、証明書チェーンの中に自分の信頼している CA (Trust Point) の証明書が含まれているかで判断することができます。

証明書チェーン

クライアントにはルート CA の証明書のみを Trust Point としてインポートしておけば、サーバはツリーの中のいずれかの CA によって証明書の発行を受ければ良い事になります。

Web of Trust

古くからメールなど使用されている PGP (Pretty Good Privacy) と呼ばれる暗号化プログラムでは、ユーザがお互いを証明することで中央集権構造の CA に頼らず信頼の輪 (Web of Trust) を形成するモデルを使用しています。これは現在で言う P2P の形態や、SNS で友達を招待する方法似ています。

  1. 現実世界での友人や仕事仲間のように相手の身元が確実に分かっている場合、相手に証明書を発行し、また相手の証明書を信頼済みリストに加えます。 A→B
  2. 相手が信頼できるかを判断する時、相手の持っている証明書の中に自分が信頼している人によって署名された証明書が含まれているかを調べます。もし含まれているならこの人は信頼することができます。 C→B

自分の信頼する主体によって信頼されているものは信頼ができるという発想は CA と同じです。

このモデルは仕事場や学校、あるいはインターネット上のコミュニティ程度の範囲で「村」が形成されている状況に適したモデルでしたが、実際問題としてそれほど広くスムーズに機能していたとは言えませんでした。また不特定多数が訪問・参加するようなサービスには向いていません。

証明書の作成

一般的な CA の利用

証明書は CA に CSR (証明書署名要求) を提出することで行われます。

工事中
Under Construction

自己署名証明書

自己署名証明書とは、証明を受ける主体と署名者が同一、つまり第三者的な CA の代わりに自分で署名した証明書です。対になる秘密鍵を用いて公開鍵とその証明書に署名を行います。

自己署名証明書には身元情報などを好きなように付けられるため、通信の中継者によって鍵以外を全く同じに偽装された証明書にすり替えられたとしても検知するすべがありません。暗号化にすり替えられた鍵を使用してしまうと中継者によって暗号内容の傍受・改ざんが可能になります。

自己署名証明書のすり替え

この不正中継はパケット閲覧より格段に大掛かりになるので何もしないよりは安全ですが、技術的には「偶発的なデータ破損が発生していないこと」だけしか保障できません。一般的なアプリケーションは安全が保障されていない自己署名証明書を使った暗号化が行われようとすると毎回セキュリティ警告のダイアログが表示されます。

しかし公開鍵を使用するアプリケーションのほとんどは信頼性が保障されている自己署名証明書を手動で追加登録 (インポート) する事ができます*1。このため、相手に安全な手段で証明書を渡すことができれば、自己署名であっても通常の証明書と同等のセキュリティを確保することができます。

自己署名証明書の安全な運用

ところで、信頼構造の頂点に位置するルート CA は自分以外に自分の証明書を保障する主体がいません。このためルート CA の証明書は自己署名証明書です。

つまりクライアントに自己署名証明書をインポートするということは、クライアントが信頼するルート CA を新しく追加するということに等しく、これによって自己署名で使用した秘密鍵で署名した証明書は全て信頼できるものとして認められるようになります。

*1 Windows なら Active Directory を使用して証明書を一元管理できます (未確認)。

独自のルート CA

OpenSSL や Windows Server の証明書サービス、 Java EE コンテナの Apache Geronimo などを利用して自己署名に使用した秘密鍵から新しい証明書を作成することができます。これは独自にルート CA を構築しているのと同じ構成です*1

独自のルート CA を構築

独自の CA を構築することで CA に支払う管理費用が不要になり、SSL やアプレット用の証明書を自由に発行することができます。独自のルート CA は組織内に大きなネットワークを持っている企業や、特定の利用者向けサービスなどで利用されています (電子政府化でルート証明書をインポートさせる官公庁も多く存在します)。

*1 単なる証明書の発行と管理を行うシステムなのでサーバの公開などは必要はありません。 OpenSSL はコマンドラインで証明書を作成します。

証明書の安全な受け渡し

自己署名や独自のルート CA といっても機能が暫定版だとか傍受や改ざんなどの技術的な落ち度があるわけではなく、公的な CA が発行する証明書と同等のセキュリティで運用することが可能です (通信相手が本当に信頼できるかというソーシャル的な意味は除きますが)。ただしそれを保障するためには証明書の安全な受け渡し手段が必須です。

  • FD, CD-ROM などの物理メディアで直接渡す。
  • 別の SSL サーバなど、安全な通信経路を経由して渡す。
  • 暗号化した ZIP などで渡し、そのパスワードを電話や書面等で伝える。
  • 暗号化されていないメールに添付したりホームページからダウンロードしてもらい、証明書のフィンガープリントを電話や書面などの安全な方法で伝えて確認してもらう。

もし安全な受け渡し方法が確保できないのであれば、証明書のダウンロードで攻撃を受けるリスクとの天秤となります*1。しかし、安全なコンタクト方法を確保できない不特定多数向けに、一般的な CA を使わずに済まそうというのであれば、甘受できる程度のリスクではないかと思います。

Java や Mozilla 系ブラウザは未知の証明書を受け入れる時、以後もこの証明書を信用するかどうかを選択できますが、この方法でインポートされた証明書はこのリスクを負っています。もっともこれは、入手した証明書のフィンガープリントをユーザ自身が確認しなければならない SSH と同程度の安全性です。

*1 現実問題、中継者が通信内容のすり替えを行うほど大掛かりな罠を張っておく価値があるなら公的な CA を使用した方法が良いと思いますが。
CVS 2008/04/16