OpenPGP -- ユーザ ID と公開鍵の有効性

no extension

OpenPGP のユーザ ID と公開鍵の有効性について興味深い議論があるので紹介します。

OpenPGP の公開鍵への署名は鍵パケットに付加するのではなく, 主鍵にぶら下がるユーザ ID のパケットに付加されます。 鍵(v4 鍵)の構成を上の記事から引用します。

Primary-Key
   [Revocation Self Signature]
   [Direct Key Self Signature...]
    User ID [Signature ...]
   [User ID [Signature ...] ...]
   [[Subkey [Binding-Signature-Revocation]
           Primary-Key-Binding-Signature] ...]

RFC 2440 によると, ユーザ ID の内容については「鍵保持者の名前やemailアドレスで構成される」以外に特に制約らしい制約はありません。 またユーザ ID は複数設定することもでき, あるいは後から追加することもできます。 つまりユーザ ID 毎に異なる署名があることになります。 実はこの仕様に問題が潜んでいます。

まず公開鍵の信用度と有効性について簡単におさらいしておきましょう。 OpenPGP の公開鍵には「信用度」と「有効性」という2つのパラメータが存在します。 「信用度」は公開鍵を使用する人が設定します。 このパラメータは公開鍵に(厳密には上述のようにユーザ ID にぶら下がる形で)署名する際に設定します。 「有効性」は設定された「信用度」を基に計算によって決まる値です。 公開鍵を使用する人からみて信用している人の署名があれば(使用者自身の署名がなくても)その鍵は信用できるとみなすわけです。 そしてこれがいわゆる「信用の輪(Web of trust)」と呼ばれる信用モデルの基本でもあります。

2つのユーザ ID が設定された公開鍵を考えてみます。

pub  1024D/1234ABCD  created: 2005-10-16  expires: never       usage: CSA
                     trust: unknown       validity: full
sub  2048g/5678CDEF  created: 2005-10-16  expires: never       usage: E
[ unknown] (1). Alice <alice@mycompany.com>
[  full  ] (2)  Becky <becky@freemail.net>

(1) は会社から正式に発行されているメールアドレスです。 この公開鍵を公開鍵サーバから受け取った Chris はこの会社とユーザを知っています。 (1) のユーザ ID には自己署名以外誰も署名していないので有効性は「unknown」です。 一方 (2) のユーザ ID は誰でも自由にアカウントを発行してくれるフリーメール・サービスのメールアドレスです。 Chris はまだ署名していませんが, 署名状況から有効性が「full」と判定されています。

さて, alice@mycompany.com から署名付きのメールが届きました。 署名結果は以下のとおりです。

gpg: Signature made 10/16/05 12:49:55 using DSA key ID 1234ABCD
gpg: Good signature from "Alice <alice@mycompany.com>"
gpg:                     "Becky <becky@freemail.net>"

この結果は本当に信用できるのでしょうか。 もし2つのユーザ ID の有効性がいずれも「unknown」であるなら以下のように警告が表示された筈です。

gpg: Signature made 10/16/05 12:49:55 using DSA key ID 1234ABCD
gpg: Good signature from "Alice <alice@mycompany.com>"
gpg:                     "Becky <becky@freemail.net>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

しかし有効性は鍵に対する評価なので, 2つのユーザ ID のうちひとつでも有効と判断されればその鍵は有効であると判断されてしまいます。 もし "Becky <becky@freemail.net>" なる人物が勝手に "Alice <alice@mycompany.com>" を名乗っているだけだとしたら? その場合 Chris は気付くことができるでしょうか。

もしメールの内容が秘密情報の交換だとすれば Chris は alice@mycompany.com に対して署名・暗号化されたメールを返そうとするでしょう。 alice@mycompany.com の有効性は「unknown」なので, 暗号化時に以下のような警告が出る筈です。

gpg: using subkey 5678CDEF instead of primary key 1234ABCD
gpg: 5678CDEF: There is no assurance this key belongs to the named user

ひょっとするとこの時点で Chris はこの公開鍵の問題に気付くかもしれません。 しかしメールの内容が緊急性の高いもので 「(メールに書かれている電話番号に)電話をして留守番電話にパスワードを入れておいてくれ」 といったものだとしたらどうでしょう。 署名の検証には成功しているだけに信用して電話をかけてしまうかもしれません。

この問題のポイントは「有効性」の対象が OpenPGP とユーザとの間でズレていることです。 OpenPGP の「信用の輪」における「有効性」はあくまでも鍵に対するものです。 一方ユーザが「有効性」を判断する対象は鍵保持者です。 そのためユーザ ID の内容の正しさが非常に重要になってくるのです。

この問題に対し GnuPG ではある程度回避可能です。 署名検証の際に「--verify-options show-uid-validity」オプションを付加します。 毎回入力するのは面倒なのであらかじめ gpg.conf に書いてしまうのも手かもしれません。 この場合, 先程の署名検証の結果はこう変わります。

gpg: Signature made 10/16/05 12:49:55 using DSA key ID 1234ABCD
gpg: Good signature from "Alice <alice@mycompany.com>" [unknown]
gpg:                     "Becky <becky@freemail.net>" [full]

これならユーザ ID 毎に有効性が示されるため, より正確な判断が可能になります。 個人的な感想を言えばこんな重要なオプションは既定で有効にして欲しいものです。

鍵保持者も鍵の管理について一考の余地があると思います。 PGP では長い間ひとつの鍵に複数のユーザ ID をぶら下げることが推奨されてきました。 ユーザ ID 毎に鍵を作成していたのでは鍵保持者も公開鍵を受け取る側も管理が繁雑になるためです。 しかし上で示した例のように使い捨てできるフリーメールのアドレスと仕事等で使うアドレスをひとつの鍵で管理するのは明らかに問題です。 鍵は目的別に分けて(できればそれぞれに管理ポリシーを設定して)運用すべきだと思います。 上で示した例で有効と判断されているユーザ ID がフリーメールのアドレスではなくもっと身元確かなアドレス(例えば客先から支給されているアドレスなど)であれば Chris は異なる判断が出来たかもしれません。

以下, 参考文献です。

暗号技術入門
暗号技術入門
posted with 簡単リンクくん at 2005.10.16
結城 浩著
ソフトバンクパブリッシング (2003.9)
通常2-3日以内に発送します。