GPG のココロ
ここでは GPG (GnuPG) のごく初等的な基礎を解説しています。
メレンゲパニックのテーマとは関係のない技術的な話ですが、 コンタクトページ や サイトポリシィ などで 利用していることもあり、 メレンゲパニックの運営に暗号化メールを送りたいけど仕組みが分からない、 という問い合わせがあったので少し紹介することにしました。
暗号化通信はディジタル生活におけるベーシックな必須技術であるにも関わらず、 とっつきにくいアイデアがいくつか出てくるので、 多くの人がその理解を諦めているのが現状です。 前提知識ゼロの人にも理解できるような入門的解説の必要性を感じますが、 ウェブ上にあまり見つかりません。
以下は GPG/PGP についてご存知ない方向けの入門的紹介です。 技術的な話であり、 メレンゲやサルサの話とは関係ありません。
GPG とは
GPG は "GNU Privacy Guard" というソフトウェアのことで、 GPG あるいは GnuPG などと表記されます。 先行の "Pretty Good Privacy" (PGP) というプロプライエタリなソフトウェアの置き換えとして、 1999年から公開されているオープンで自由な暗号化ソフトで、 暗号化通信をする際のデファクトスタンダードです。 開発の経緯や歴史、ドキュメンテーションなどは、 公式サイト The GNU Privacy Guard (外部リンク) に詳しいので関心のある方はご参照ください。
マニュアルも非常に丁寧に作成してありますが、 丁寧すぎて全体像が分かりにくいですし、 ツールのハウツー以前に概念を理解したいという人にとっては ややとっつきにくいかもしれません。
むしろ、ツールの使い方そのものは、 概念さえ理解すればそれほど難しくありません。 様々な実装があり、 アプリケーションごとに使い方は多少変化しますが、 大事なのはアイデアの「ココロ」を理解することです。
目次
暗号化の目的
まず、そもそもどうして通信を暗号化をするのか。 一般に暗号化通信には4つの機能があるといわれます。 それぞれ英語の頭文字をとって CIAN とも言われます。
- Confidenciality 機密性
- Integrity 完全性
- Authentication 認証
- Non-repudiation 否認防止
通信の性質によってはこの4つのうち、 いくつかの要件を満足すれば充分な場合もあります。 常にすべてを満足する必要はありません。
例えば、 アリスは職場のダンス仲間であるボブに、 週末のパーティに一緒に行こうというお誘いのメッセージを送りたいと思っているとします。 ただし、このメッセージには親密な内容や法に触れるかもしれない部分があるため、 ボブ以外の人、例えばシステム管理部のマロリィには知られたくありません。 また、ボブはそれが本当にアリスからの誘いであればパーティに行きたいと思っていますが、 アリスの名を騙る別の人物に誘われているのだとしたら行きたくありません。
機密性
機密性とは通信内容が他者に傍受されないことを保証すること。 また、傍受されても内容を理解できないことを含む概念です。 アリスが送る内容はボブ以外が理解できないようになっていなければなりません。
ところが、メッセージがメールや SNS をはじめとするウェブサーヴィスを利用して ネットワーク越しに送信されるとき、 複数のサーバを経由して相手のところに届きます。 このときメールの内容が平文(誰にでも読める暗号化されていない文)で書かれていれば、 各サーバの管理者や、データを傍受した悪意の第三者は通信内容を読むことができます。 これではボブ以外の人にメッセージを読まれてしまいます。 あるいは、仮に悪意の第三者がいなくても、サーバやシステムのバグが原因で情報が流出したり、 ヒューマンエラーで意図しない相手に誤送信されるケースは 様々なサーヴィスで日常的に発生しています。
これを防ぐには平文を何らかのアルゴリズムで暗号化して送信することが必要です。 この暗号化メッセージを復号することがボブ以外に不可能であれば、 機密性が担保できるというわけです。
ただし、ひとつだけ注意したいのは、 ここでの機密の範囲は通信の内容についてだけで、 アリスからボブに通信があったという事実までは隠せません。 サーバの管理者はアリスがボブに何らかの秘密の通信を行ったことは認識できます。 一般的な暗号化通信には通信の事実そのものを秘匿する能力はないことは覚えておきましょう。
完全性
完全性とは送信者の書いたメッセージが必要十分なかたちで受信者に届くことを意味し、 欠損や重複や改竄がないことを保証するものです。
通信中に情報が悪意の第三者によって改竄されるとか、 通信のミスで一部が欠落してしまうことは様々な原因で起こり得ますが、 暗号化技術を利用するとボブはこうした改竄や欠落をただちに発見できるようになります。 受け取ったメッセージが一言一句アリスの書いた通りに間違いないと確信できるわけです。
認証
認証とは誰が誰にメッセージを届けたのかが明示されることです。
認証機能を満足する暗号化メッセージを受け取ると、 ボブは届いたメッセージが間違いなくアリスが書いたものだと確認できるので、 アリスの名を騙る別人からのメッセージを受け取った場合にはそれに気付くことができます。
実は、厳密な意味での認証には技術的な問題以上により根本的な難問があるのですが、 それについては後述します。
否認防止
否認防止とは送信者が送信事実およびその内容を拒否できないことを保証するものです。 また、受信者が受信した事実を拒否できないようにすることも指します。
否認防止の機能を持つ暗号化メールによって、 アリスがボブに週末のサルサパーティの約束をしたら、 実はあのメールを送ったのは私ではない、 私はパーティに行くなどとは言っていない、 と後から否認することが論理的にできなくなります。
暗号化アルゴリズムの種類
4つの機能のうち、どれを満足できるかは暗号化に用いるアルゴリズムによって変化します。
実際の GPG による暗号化通信では、 様々な暗号化アルゴリズムを組み合わせて使用することで、 それぞれの場面の必要に合わせて CIAN の機能を提供してくれます。
ここでは共通鍵暗号と公開鍵暗号およびハッシュダイジェストについてみてみましょう。
共通鍵暗号
いま、アリスはボブに直接対面で会って事前に暗号化のアルゴリズムを伝えておくことが 出来るとしましょう。 このケースでは事前にとり決めたパスワードを使った 暗号化メッセージをボブに送ることができます。 こうして送られるメッセージはボブ以外の人には読めませんし、 ボブには読めるので「機密性」は担保されます。 また、このとき共有したパスワードはアリスとボブ以外に知っている人がいませんから、 このパスワードを使った共通鍵暗号で復号化できる、 という時点で確かにアリスが送ったメッセージであることをボブは「認証」することもできます。 つまり、共通パスワードを使った暗号化メッセージは、 「機密性」と「送信者の認証」が可能な方法ということになります。
このように、事前にアルゴリズムやパスワードを共有している者同士の間で使える暗号化方式を、 「共通鍵暗号」といいます。 もっとも一般的に暗号化というとこの共通鍵暗号のイメジが湧く人が多いのではないでしょうか。
ところで、ネットワーク越しでのコミュニケーションを考えるとき、 共通鍵暗号には重大な欠点があります。 それは、どうやってパスワード自体を相手に知らせるのか、 という問題です。 先の例のように、 事前に直接会ってパスワードをアナログに交換するという方法が古典的ではあるのですが、 この場合でさえ安全とは限りません。 伝達の現場での盗聴や共有したパスワードをシステムに入力するまでの段階での漏洩など、 セキュリティ的には必ずしも安心できる方法ではないのです。 というのもある情報が2人以上の人間に共有されるとき、 その経路がオンラインであれオフラインであれ、 それが表明され、平文で交換される場合には、 そのときに盗聴・盗撮されたり、傍受される可能性を排除することができないからです。 しかも、インタネットを前提とするコミュニケーション環境の場合は「事前に直接会う」という ことがそもそも難しいケースが多いという問題も厄介です。
パスワードを平文で伝達しようとして漏洩したり、 傍受されてしまっては全く無意味ですね。 パスワードの伝達には最低でも「機密性」と「認証」の機能を持った通信手段が必要です。 暗号化通信をするためのパスワードを送信したいのに、 パスワードを送信するのに暗号化通信が必要という状況になってしまいました。
公開鍵暗号
この問題を解決する極めて優れた暗号が公開鍵暗号です。 GPG の特徴のひとつはこの公開鍵暗号を使用するという点です。
公開鍵暗号では、各利用者はそれぞれ公開鍵と秘密鍵のセットを持っています。 公開鍵とは秘密鍵と一緒に生成される共有用の鍵で、 悪意のある盗聴者をも含む、世界中の誰に渡しても構いません。 一方の秘密鍵は決して自分以外の誰にもアクセスできないように厳重に管理します。 ここで重要なのは公開鍵と秘密鍵が以下のような性質を持っていることです。
- 公開鍵と秘密鍵がペアになっている
- 公開鍵で暗号化したデータは秘密鍵でしか復号できない
- 秘密鍵での署名は公開鍵で検証できる
- 公開鍵から秘密鍵を生成したり類推したりすることが出来ない
最もよく知られた公開鍵暗号の場合、 これらの性質は、巨大数の素因数分解は極めて困難(実質的に不可能)だが、 巨大な素数同士の積を計算するのは簡単である、 という計算機科学上の事実によって担保されています。 こんな簡単な話でインタネット中のセキュリティが守られているなんて意外な感じがしませんか。 アルゴリズムそのものに興味がある人はいろいろ調べてみてください。
さて、公開鍵暗号を使って機密データを送信する手順は次の通りです。 まずアリスはなんらかの方法でボブの公開鍵を手に入れます。 この公開鍵はパスワードと違って誰の手に渡っても構いませんから、 メールに添付しても、どこかのサーバに置いておいても構いません。 差し当たってここではアリスはそれが本当にボブの公開鍵であることを確信できるとします。 アリスは入手したボブの公開鍵で秘密のデータを暗号化します。 このボブの公開鍵で暗号化されたデータはボブの秘密鍵を使わないと復号できません。 アリスは暗号化したデータをボブに送信しますが、 この途中で誰かに傍受されても全く心配ありません。 ボブの秘密鍵を持っている人間以外にはどうやってもデータを読むことが出来ないのですから。 実は暗号化したアリス自身にもこの暗号化メッセージを復元することはできません。 もちろん、アリスは暗号化前の原文を持っているので復元の必要はありませんが。
このような仕組みであるため、 共通鍵暗号では難しかったパスワードを共有するという課題が、 公開鍵暗号では上手くクリアできていることが分かります。
また、通信中にわずか1バイトでも欠損や改竄があると、 ボブはこのメッセージを復号することができなくなります。 このため、そのメッセージは完全ではないとただちに分かります。 このように、公開鍵暗号を使うことで通信の「機密性」と「完全性」が保証できます。
ちなみに、この公開鍵暗号通信を使えば共通鍵暗号のパスワードも安全に送信できますよね。 公開鍵を交換し合っている人同士であれば ネットワーク越しでもパスワードを暗号化して安全に共有することができます。 するとそれ以降は公開鍵暗号通信ではなく共通鍵暗号でやりとりすることもできるのです。 実際の暗号化通信では計算コストの節約のためこのような合わせ技もよく利用されています。
さて、公開鍵暗号のもうひとつの特筆すべきメリットは暗号化と同じロジックを使って、 「署名」をすることが可能であるという点です (別々のアルゴリズムを使うこともできます)。 署名とは秘密鍵を使って特定のメッセージに証明を作成して付与すること。 公開鍵を持っている人なら誰でも確かにその本人の秘密鍵で署名されたものであることを、 その人の公開鍵を使って検証することができるのです。 また、同時にメッセージが「完全」であることも分かります。 秘密鍵を持っているのはホンモノの送信者当人だけですから、 つまり、受信者が「送信者を認証」することが可能になる訳ですね。
もちろん、「署名」という言葉が意味する通り、 署名付きのメッセージは、送信者が後でその内容を否定することができません。 内容の「完全性」と「送信者の認証」を保証するということは、 必然的に「否認の防止」の機能を持つことになるからです。
ハッシュダイジェスト
ここでもうひとつ、 暗号化通信で使われるハッシュダイジェストについても見てみましょう。 これは元のメッセージ(あるいはファイル) から固定長の短い文字列を計算するだけの単純なアルゴリズムで、 出力される結果は次のような性質をもっています。
- 元のメッセージが同じなら必ず同じ結果になる
- 元のメッセージが1バイトでも異なれば結果は大きく異なる
- 出力されたハッシュダイジェストからは元のメッセージを復元・予測できない
- 異なるメッセージが同一の結果を出力することは確率的に極めて小さい
これはハッシュ関数と呼ばれる一方向の関数は存在するが、 逆方向の演算が事実上不可能であるようなアルゴリズムによって実現されています。
これは例えば巨大なファイルをサイトからダウンロードさせるケースで役立ちます。 ウェブ上にファイルのハッシュダイジェストの値を併記しておくと、 ダウンロードした人は手元で自ら保存したファイルのダイジェストを計算し、 その値がウェブ上のものと一致することを確認することで、 ファイルが欠損なしの完全なかたちで取得できたと諒解することができるからです。
このようにハッシュダイジェストを利用することで手軽に(低コストで) 「完全性」を担保することができます。 ただし、ハッシュダイジェストを単体で用いて保証できるのはメッセージの「完全性」のみ、 元のメッセージ(あるいはファイル)自体は原像データのままでやりとりされるので 「機密性」はありません。 送信者や受信者を特定する能力もないので「認証」には使えません。 一方で、上手に使うと「否認防止」に使える局面があります。
例えばアリスは件のパーティの場で、ボブにドリンク当てゲームを提案するとしましょう。 もしパーティでボブが最初に頼むドリンクをアリスが事前に予想して当てることができれば ボブはこの夜アリスが飲むドリンクをすべておごらなければなりません。 外れれば反対にアリスがボブのドリンクをおごるというルールです。
このとき、 アリスはボブがドリンクを頼む前に、 予めボブの注文の予想を明示しておかねばなりません。 ただし、ボブの方もアリスがハバナ・クラブといったのを聞いた後に オーダをバルセロに変えるといったことが可能ですから、 ボブは注文前にアリスの予想を知ってはいけません。
いわゆる碁や将棋における「封じ手」のような仕組みが必要になる訳ですが、 これをハッシュダイジェストで実現することができるのです。
アリスはあらかじめボブへのメールに 自身の予想を示すハッシュダイジェストの値を沿えておきます。 このハッシュダイジェストは例えば「santateresa+(nonce)」 (nonce とは使い捨ての意味のない文字列のことで例えば "YMHBrnkY") を元メッセージとして計算されたものです。 ボブはダイジェストの値だけ先に受けとりますが、 それはまったくランダムな文字列(例えば "3f8630e9")なので、 アリスの予想を類推することはできません。
はたしてボブはサンタ・テレサを頼みました。賭けはアリスの勝ちとなり、 アリスは nonce と合わせてダイジェストの元メッセージ (ここでは "santateresa+YMHBrnkY")をボブに明かします。 ボブはそのハッシュダイジェストの値が事前に提示されていた "3f8630e9" と一致することを確認し、アリスの勝利を受け入れます。 審判や立ち会い人はいませんが、どちらも勝負にアヤを付けることはできません。 この夜、ボブはアリスにコローナを1本、ロン・サカパを3杯、 フローズン・ダイキリとモヒートまで飲まれてしまいました。
ここでは、別の元メッセージを使って同一のハッシュを生成することは 現実的に不可能であること、 また、ダイジェストの値から元メッセージを類推できないという ハッシュダイジェストの性質が上手に利用されています。
このようにハッシュダイジェストは「完全性」を簡単に検証でき、 また「否認防止」を要求する際にも応用することができます。
GPG の運用フロー
こうした様々なアルゴリズムを組み合わせることで 優れた仕組みを実現している GPG の暗号化通信ですが、 実際に始めてみるには、 自分の鍵や他者の鍵をたくさん管理する必要がでてきます。 デフォルトだけでも自分の鍵は最低4つ (署名用・暗号化用のそれぞれ秘密鍵・公開鍵)もあり、 通信したい人の数だけ相手の公開鍵束を持っていなければいけませんからね。 GPG はこうした煩雑な管理や暗号化・復号化・署名などの処理を 手軽に行えるインタフェイスを提供してくれます。
よく設計され、充分にテストされた実績ある自由ソフトが公開されていることは、 頼もしい限りです。
公開鍵の交換
ところで、アリスがボブに暗号化メッセージを送りたいとすると、 まず手に入れなければいけないのはボブの公開鍵でした。 伝統的にはキーサーバを利用するのが GPG 流で、 このサーバにはメールアドレスと 合わせてたくさんの個人や組織の公開鍵がアップロードされています。
メールアドレスから目的の人の公開鍵を探してもよいのですが、 ここで問題なのはなりすましです。 ボブの名を騙ってキーサーバに公開鍵をアップしている偽者をボブだと信じてしまえば、 もはや暗号化通信は安全でもなんでもありません。 そう、アリスにとって最も困難なのは ボブの公開鍵が確かにボブのものであると信頼することなのです。 キーサーバの情報から分かるのは、 せいぜいあるメールアドレスを持つ人物がある公開鍵をアップしていて、 その人物にしか読めない機密文書を送信することが可能ということだけです。 その公開鍵とメールアドレスの管理者が 本当にアリスの知っているボブかどうかは分からないのです。
GPG/PGP 以外の流儀のセキュリティ技術では、 中央認証局と呼ばれる権威と信頼がある(とされる)公的性格を持った機関に 鍵の身元確認を依頼・委譲する場合もあります。 認証局は公開鍵とその所有者の関係を確認・管理する中央集権的な仕組みで、 SSL/TLS や S/MIME などの技術ではこうした方法が採用されるのですが、 個人間での気軽なやりとりに第三者機関を利用するというのも大袈裟な話。 制度設計の観点でも、認証局は単一障害点になりますから、 高い水準で可用性や安全性を担保しなければいけません。 このためのコストを誰がどう負担するかという問題が生じます。
ちなみに、ディジタル世界の中だけの付き合いであれば、 鍵の所有者を現実世界の人物と突き合わせる必要がなく、 ある秘密鍵を持っているということ自体が最終的なアイデンティティなので手間はかかりません。 秘密鍵を失うことは、単にディジタル世界における人格の消失を意味します。 一方で現実の人間は GPG の鍵を失くしたからといって人でなくなる訳ではありませんから、 鍵の所有者を確認したり、紛失や失効を取り扱う必要が生じます。
キーサーバでは一応 "web of trust" という仕組みで鍵の信頼性を測れるようになっています。 これはいわば信頼できる人が信頼している人(または鍵)は信頼できる、 という類いの基盤設計で、中央集権的な認証局に依存しない分民主的な方法ではありますが、 伝言ゲームがすぐに破綻することを考えてもあまり安定したものでないことは明白です。 認証局方式も突き詰めていえばこの伝言ゲームのお役所風のヴァージョンに過ぎません。 信頼の根拠を他者に肩代わりしてもらっているだけですからね。
ではどうするか。 手っ取り早いのは直接ボブに電話を掛けること。 どんな経路でもいいので、 ボブの公開鍵を入手したら自分でその指紋を確認し、 ボブに電話して彼の鍵の指紋を読み上げてもらうことです。 手元に届いたボブの鍵の指紋と読み上げ内容が一致することを確認します。
ここで鍵の指紋とは、 おおよそ鍵のハッシュダイジェストみたいなものだと思ってもらって構いません。 ダイジェストなので、指紋が一致する別の鍵を作成することは事実上不可能です。 公開鍵ファイルはその全部を人が口頭で読み上げるにはちょっと長すぎますが、 指紋(=ダイジェスト)なら短いので確認しやすいという訳です。
このように GPG を使う人々の間では、 お互いの公開鍵を交換し、その指紋を確認し合う、 というプロセスがとても大切な意味を持っています。 それはお互いのディジタルアイデンティティを信頼し合う儀式に他なりません。
実際、口頭や電話での確認をより簡単にするため、 GPG/PGP のコミュニティでは無機質な鍵の指紋を勘違いしにくいワード列に変換する PGP Word List (外部リンク) なんてモノまであるんですよ。 もちろん、今の時代、電話の声だって簡単にハックできますから、 もっと確実には直接顔と顔を突き合わせて、 確認し合うのがベストプラクティスということになります。 手渡しで交換する紙の名刺に自分の鍵の指紋を印刷しておく方法もよいやり方です。 不思議に思う人もいるかもしれませんが、 個人間でディジタル証明を信頼するにはこんなアナログな方法に頼るしかないのです。
このように、暗号化通信の最大の難関がこの深い意味での「信頼」です。 公開鍵の真性を信頼できなければ「認証」プロセスは根元から崩れてしまいますが、 これが困難なのは技術上の問題というよりも、 認識論的な問題だからです。
この状況は一見、 共通鍵暗号でパスワードを共有するときの困難に似ているように見えるかもしれませんが、 まったく違います。 パスワード共有の難しさはどうやってネットワーク越しに「機密性」を担保するか、 という課題でしたが、ここでの問題は暗号化云々以前に 「人を『信頼』することは可能か」という、 もっと哲学的な問題に関わっています。
そもそもの議論として、どうしてアリスはボブがボブだと認識できるのでしょうか? 最初に会ったときにボブだと紹介されたから、 といってもそれが嘘でない証拠はありませんし、 ボブ自身も自分はボブだと思い込んでいるだけかもしれません。 本人も家族も気付かないうちに病院で取り違えられており、 本当はクリスだったという可能性だってゼロではありません。 あるいは、 ボブのような顔で、 ボブのように話し、 ボブのように歌い、 ボブのように踊る者が、 実はメレンゲ好きの変装名人アルセーヌ・ルパンである可能性だって棄てきれません。
このように極端な懐疑論を持ち出すと、 人物の身分証明、つまり「認証」というのは根本的には不可能で、 手続上の問題というよりも記号接地問題になってきます。 話しぶりがボブそっくりでも、 顔がボブの顔でも、 ID カードを持っていても、 秘密のパスワードやボブが小さい頃に飼っていた猫の名前を知っていても、 指紋や静脈や遺伝子情報が一緒でも、 それらは盗聴したり偽造したり詐称したりできます。 そもそもオリジナルが改竄されていたり間違いであるかもしれません。
権威ある公的機関や三つの頭を持つ番犬にこの人はボブである、 と証言してもらってそれを信頼する、とする方法は一見上手くいきそうですが、 よく考えれてみれば、 ボブを信頼するよりもこの権威ある機関を信頼することの方が簡単な気がする、 というだけで問題を横滑りさせたに過ぎません。 認証局の方がボブ本人のいうことより信頼できるかどうかは相対的な話ですし、 第三者が関与することで認証プロセスが複雑化し、 技術的なエラーやハックによる誤認証の可能性が増加することさえ考えられます。
この問題は究極的には理性や技術の範囲では解決のしようがありません。 人が人を「信頼」するプロセスを律しているものは論理以前の神秘の呪術です。 したがって個人間の暗号化通信の技術的トピックとしては、 ボブは本当にボブなのか、というこの深淵な問題には入り込まず、 ボブと名乗り、ボブのメールアドレスを使用し、 ボブの公開鍵に対応する秘密鍵を所有している存在、 という浅いエンドポイントの「認証」までに留めておくべきでしょう。 そしてそれが目の前のボブと同一なのかどうかを確認する場合でも、 素朴な日常感覚としてはボブに直接会って鍵の指紋を確認するところまでになるでしょう。 ですからここでは、アリスにとってその全五官を動員してボブと信じうる人が、 この公開鍵(の指紋)は僕のものだよ、 と目の前で言ってくれればその鍵はボブのものとして 「信頼」できると信じることにしましょう。
とにもかくにも、アリスがボブの公開鍵を「信頼」したように、 ボブもアリスの公開鍵を「信頼」します。 これで両者はお互いの公開鍵を交換し、 それがまさしく相手のものであることを「信頼」できたので、 通信対象としてお互いを「認証」することができるようになりました。
暗号化・署名と復号化・検証
そうして、アリスは入手したボブの公開鍵を使ってメッセージを暗号化し、 「機密性」を担保します。 同時にこのメッセージは復号時に「完全性」が確認できるものになりました。 したがって、ボブはこのメッセージが自分の秘密鍵で復号できることを確認すれば、 送信者以外の誰にも内容を知られていないこと、 メッセージは一切の欠損も改竄もない完全な状態で届いたことを確認することができます。
ただし、「署名」が付いていない暗号化メッセージの場合、 本当に送信者がアリスなのかまではボブには判断できません。 ボブの公開鍵を知っている人は他にもいるはずだからです。 したがって、アリスにメッセージ内容の「否認の防止」を求めることもできません。
そこでボブはアリスに「署名」つきの暗号化メッセージを送ってくれるように依頼しました。 これでボブはアリスの公開鍵を用いて、 確かにアリスが送信者であることを検証することができるのです。 また、確実にアリスが送ってきたメッセージであることが「認証」できているのですから、 アリスはその内容を後で「否認することは出来ない」という訳です。 以上みたように、 「機密性」「完全性」「否認の防止」は、 「認証」さえ上手くいけば技術的に簡単に担保することができます。 これが公開鍵暗号による通信の非常に大きなメリットです。
こうしてアリスからのサルサパーティのお誘い(ドリンク賭博の「封じ手」付き)は、 アリスとボブ以外の誰にもその内容を知られることなく、 また一言一句欠損や改竄がないことを担保した状態で、 アリスがボブに送ったメッセージであることをボブが検証可能な状態で届くことになりました。
GPG の具体的な使い方
GPG/PGP の概念については以上のことをなんとなく把握してもらえれば、 初心者としては充分ではなかろうかと思います。 ここからは、より具体的に GPG を利用した暗号化通信の手順を見ていこうと思います。
鍵の作成とその機能
初めて GPG をインストールしたら最初に行うのは自分の鍵の作成です。 なお、 GPG の実装やヴァージョンによって入力の方法や設定項目が異なると思いますので、 そのあたりは適宜読み替えてください。 コマンドラインからの場合は以下を入力してみてください。
gpg --gen-key
これで、対話形式で鍵の設定情報を入力できます。 分からないところ、こだわりのないところはデフォルトで充分だと思います。
まず、 キータイプは RSA でいいでしょう。 これは公開鍵暗号のアルゴリズムのことで、 RSA は署名にも暗号化にも使える公開鍵暗号のデファクトです。 また、キーの長さはデフォルトで充分ですし、 長くしたい人は 4096 にしてもいいと思います。 実質的な安全性はさほど変わらないとされています。 なお、ここでプライマリキーとサブキーの2種類のキーの設定がそれぞれ必要です。
次にキーの有効期限を設定します。 以前はそれなりに短い期間を設定して、都度更新する方がお行儀がよいとされていました。 ただ、有効期限は後で変更もできるので最初はあまり気にする必要はないですし、 キーサーバを使わない運用であれば有効期限なしに設定してもいいと思います。
そして、名前とメールアドレスを設定しましょう。 鍵に紐付けられるパーソナルデータは、自分の名前とメールアドレスのみです。
最後にパスフレーズを設定します。これは鍵のステータスを変更したり、 他の鍵を信頼したり、暗号化メッセージを復号化したりする場合に必要になる大事なものです。 GPG は秘密鍵ファイル (something you have) と、 パスフレーズ (something you know) の2要素認証になっています。 設定したら決して忘れないようにしておきましょう。
これで鍵の完成です。 秘密鍵の鍵束を確認するには
gpg -K
と入力してみてください。公開鍵の鍵束を確認するには
gpg -k
とします。
さて、鍵の作成ではプライマリキーとサブキーの2種類を作成しました。 プライマリキーとは署名に使う鍵で、 これの秘密鍵が究極的に最も重要なディジタルアイデンティティになります。 極端にいえば、これさえ盗まれなければ問題ありません。 プライマリキーに対して、サブキーは必要ならいくつでも作ることができます。 デフォルトでサブキーはひとつ作成され、 プライマリキーとサブキーの2種類のセットになっています。
なぜプライマリキーとサブキーを分ける必要があるのでしょうか。 それは鍵の機能に応じて使う鍵を分けて運用するためです。 GPG では鍵の機能として
- Certification 鍵への署名
- Signing 署名
- Encryption 暗号化
- Authentication 認証
の4つの機能があり、それぞれの鍵ごとに使用可能な機能を設定できます。
既に鍵には大きく署名と暗号化のふたつの機能があることを見てきましたが、 まず署名について考えてみましょう。 署名とはあるメッセージが完全であることの証明を 自分の秘密鍵を用いて作成し付与する操作でした。 署名は任意のデータに対して行うことができるので、 鍵そのものに対しても署名することができます。
GPG では素性の正しい鍵だと信頼したことを、 自分のプライマリキーで署名して表現します。 信頼されていない鍵は、 自分で作成したものであれ、他者の公開鍵であれ、使用できません。 ですから、手元の鍵束には必ず署名を施し、 どの程度信頼があるかをラベリングする必要があるのです。 これは署名といっても鍵管理のプロセスで使用する署名なので、 誰かにメッセージを送信するときに行う一般的な署名 (S) とは区別して certification (C) と呼んでいます。 とはいえ、技術的にはただの署名ですし、これを行うコマンドも実際 "sign-key" です。 ちなみに、プライマリキー自体は自分が手元で作成したものですから、 この鍵の信頼度は究極 (ultimate) です。 人から貰ったものでも、 どこかからネットワーク越しにコピーしてきたものでもないですからね。 この究極の信頼を持つプライマリキーで信頼を刻まれた鍵は、 それを使って署名したり暗号化したりするのに充分な (full) 信頼があると考えるのです。
さて、自分が鍵管理に使う鍵や、 メッセージに署名を付与する際に使う鍵は自分のアイデンティティそのものなので 決して人に渡したり共有したりネットワーク越しに通信したりしてはいけません。 複数の人が同じ鍵を持つと「認証」も「否認の防止」もできなくなります。 この署名用の秘密鍵が流出してしまうと、 その鍵ペアを破棄してもう一度新しいアイデンティティを最初から作り直す必要が生じます。 これはディジタル世界でのゼロからのやり直しを意味します。 もちろん、すべての通信相手に新しい公開鍵を配布しなおさなければなりませんが、 その際にも自分のアイデンティティを証明する方法がないので、 再び全員に電話したり、対面で会ったりして、指紋の交換からやり直さねばなりません。 大変な骨折りですし、相手にとっても負担が大きいですね。 最悪の場合、 先に流出した鍵を破棄 (revoke) する旨をすべての通信相手に伝達することが、 現実的に不可能なケースもあるかもしれません。
一方で、暗号の復号化に使うサブキー (E) の秘密鍵の場合はそれが単独で流出したとしても、 それは単にそれ以降その鍵を使わなければよいだけです。 既存の暗号化されているデータは秘密鍵が流出した先の第三者に読まれる可能性がありますが、 これはもはや覆水盆に帰らず。 できることとしては、 鍵を破棄して新しい暗号化用の鍵ペアを作成し、 以後は新しい方を使うようにするだけです。 キーサーバなら公開鍵を破棄して新しいものに更新するだけで済みますし、 そうでない場合でも、通信相手には新しい公開鍵を署名付きで送ればそれだけで充分です。 自分のプライマリキーは生きていますから、 相手はその署名を信頼して公開鍵をアップデートすることができます。
ところで、署名用の鍵と異なり、 暗号化ファイルをチームで共有するケースでは 暗号化用の秘密鍵は他の人と共有しておきたい状況がありえます。 署名用の鍵と暗号化用の鍵を分離しておけば、 暗号化用の秘密鍵を共有する必要が生じた際にもプライマリキーを渡す必要がありません。
こうした事情もあって、 最低限、署名 (S/C) に使う鍵と暗号化 (E) に使う鍵は分けるのが ベストプラクティスとされています。 決して共有してはいけない鍵と、 共有する(可能性のある)鍵は分離しておくべきということですね。 さらに、暗号化用の鍵には、 他者との共有やエスクローの可能性があるという性質から、 目的ごとに複数個の暗号化用鍵を用意しておきたいという要求がありえます。 そうした状況に対応できるよう、 GPG ではプライマリキーにサブキーを何個でもぶら下げられる構造になっています。 運用によっては鍵管理に使用する鍵への署名用の鍵 (C) と 日常的にメッセージへ署名するための鍵 (S) も分ける場合があります。
もちろん、もっとカジュアルに使いたい個人ならプライマリキーに全部の機能(SCEA) を乗っけてしまうという方法だって採用できます。 専ら個人で使う用途で、秘密鍵のシェアは決してないという場合なら 署名用と暗号化用の鍵を分ける理由はないだろうと考える場合です。
ただ、このケースでもちょっと注意が必要なのが、 当局による法的な要請があった場合にどうするか、 という問題です。 例えば緊急事態条項などが定められている国家では、 戦争などの有事の際には暗号化通信が禁止されたり、 暗号化鍵を強制的に提出させる場合があります。 実際にいくつかの国ではこうした法律が存在しますし、 有事となればドサクサに紛れて特措法などを通して強制執行することも考えられます。 万一こうした自体が生じた場合、 署名用の鍵と暗号化用の鍵が共通であればその鍵を提出しなければなりません。 一度でも他人に渡った署名用の秘密鍵は無意味になり、 ディジタルアイデンティティを喪失する結果になります。
暗号化用の鍵には暗号化の機能のみを持たせ、 他の機能を混ぜないというのはこうした事態を想定した場合にも望ましい考え方です。
ちなみに、鍵の機能としての「認証」(A) とは本来の GPG の利用目的からは外れるのですが、 SSH の鍵として GPG の鍵を流用する使い方のことで比較的新しい用途です。
まとめると、プライマリキーとサブキーの使い分けとしては、 プライマリキー (SC) とサブキー (E) を基本にして、 必要ならば (S) 専用や (A) 専用をそれぞれ追加する、 あるいは (E) 専用のサブキーを複数個追加するといった運用がいいと思います。 また、 SSH 用の認証機能 (A) をプライマリキーに追加して、 プライマリキー (SCA) とサブキー (E) という組み合わせもよく使われます。
ちなみに (S) 専用のサブキーを追加するメリットとして、 これを行っておくとプライマリキーの秘密鍵を PC から退避しておくことができる、 という点があります。 日常的にラップトップを持ち歩く人の場合、 紛失や盗難のリスクを考えて、 プライマリキーの秘密鍵を入れた状態にしておきたくないケースがあると思います。 日常的に暗号化や署名を行う人でも、 プライマリキー (SC)、サブキー1 (S)、サブキー2 (E) の3点セット構成にしておき、 メッセージへの署名にはサブキー1 (S) を使うようにしておくと、 プライマリキー (SC) の秘密鍵は使わないので普段は PC から退避して、 USB やセキュリティキーなどに保存しておくことができます。 プライマリキーが必要なのは新しい公開鍵を信頼する場合や 鍵の設定変更のときだけなので、 運用スタイルによっては滅多に出番がありません。 そういうときだけ USB を差して certificate すればよいという訳です。
公開鍵のエクスポートとインポート
では実際に公開鍵の交換の手順を見ていきます。 自分(アリス)の公開鍵をテキスト形式で出力するには以下のようにします。
gpg --output alice-gpg-pubkey.asc -a --export alice@example.com
このファイルをウェブサイトに掲載したりメールで頒布したりすることで 他の人が暗号化メールを送信できるようになります。 なお、公開鍵はテキスト形式とは別にバイナリ形式でも出力することができます。 全く同じ内容なのでどちらを使っても構いませんが、 テキストの方がそれが何か分かりやすいということもあって、 最近ではテキスト形式で配布されているケースが多いように思います。 次に、ボブの公開鍵をインポートするには以下のようにします。
gpg --import bob-gpg.pubkey.asc
インポートしただけでは充分ではありません。 本当にこの鍵を信頼するかどうかを指示する必要があります。 ボブから直接鍵の指紋を教えてもらい、 この鍵の指紋と一致するか確認します。
gpg --fingerprint bob@example.com
ボブから電話か対面で教えてもらった指紋と上記で表示される指紋が一致することを確認したら、 この鍵をボブの鍵として信頼します。 具体的には自分(アリス)のプライマリキーでこの鍵に署名するのでしたね。
gpg --sign-key bob@example.com
これでアリスはこのボブの公開鍵を使用することができるようになりました。 なお、鍵に署名するときにはパスフレーズが必要になりますので、 思い出しておきましょう。
ユースケース
ではごく簡単なユースケースを見てみましょう。 最初はメッセージへの署名です。
ここに "message.txt" というファイルがあるとします。 このファイルへの署名を作成します。
gpg -a -b message.txt
署名ファイルも公開鍵のファイルと同じようにテキスト形式かバイナリ形式か選択できますが、 今回はテキストで作成します。 "message.txt.sig" というファイルが同じディレクトリに作成されたはずです。 このファイルを "message.txt" と一緒に送付してあげることで、 相手は送信者を「認証」でき、 メッセージ内容が「完全」なかたちで送られたことを確認できます。
この署名を検証するには
gpg --verify message.txt.sig message.txt
とします。これで署名が正しいことを確認でき、 万一、署名かメッセージに改竄や欠損があればこの時点でただちに検知できます。
次にこのメッセージを暗号化してみましょう。
gpg -e -r alice@example.com message.txt
ここではアリス自身の公開鍵を使って暗号化してみました。 すると "message.txt.gpg" というファイルが作成されました。 このファイルを覗いてみると、理解不能な暗号になっていることが分かります。 では、この暗号化されたファイルを復号してみましょう。
gpg -d message.txt.gpg
アリスは自身の秘密鍵も持っていますから復号化できます。 こうして "message.txt" が復号されます。 ここでもパスフレーズが必要なことに注意してください。
個別の GUI ツールやメーラソフトなどではより簡便に使える仕組みがあるものもありますが、 ここで挙げた程度のコマンドを理解しておくとインタフェイスに依らず、 運用にも困らないと思います。
リテラシとしての暗号化通信
このように暗号化通信はただ秘密のメッセージを送れるというだけでなく、 「完全性」や「否認防止」を保証する機能を果たすことができます。
ちなみに、実際の GPG では様々なユースケースに対応できるように、 もっと細かい創意工夫が様々に凝らされています。 道具としてその使い方に習熟するにはドキュメントや解説書にあたってください。
さて、通信の秘密を保つにはこれくらいの基礎知識は最低限必要ということですが、 なかなか理解も運用も大変です。 「21世紀の油田」とも言われる個人情報を狙って、 テックジャイアンツや国家による通信の盗聴・監視・濫用が横行している実情を知ってなお、 ともすると「自分はドリンク賭博はしないし、別に人に知られて困ることなんかないから 暗号化通信なんて面倒なことは必要ない」と考えるのんびり屋さんもいるかもしれません。 そのような人には以下のエドワード・スノーデンの言葉を一度味わって欲しいと思います。
自分には隠すものは何もないからプライヴァシの権利なんてどうでもいいという主張は、 自分には言うべきことは何もないから表現の自由なんていらないということと同じだ。 誰も自分に権利が必要な理由を証明する必要はない。 正当化の義務は権利を侵害する側にあるのだから。 自分にとって役に立たないからといって他の人の権利を捨てていいことにはならない。 もっと簡単にいえば、多数派は少数派の自然権を勝手に捨てることはできないのだ。
(エドワード・スノーデン、私訳)
表現の自由やプライヴァシの権利は、 個的な嗜好や都合を擁護するためではなく、 まして悪意ある放言や情報の独占を正当化するためでもなく、 大資本や政治権力の暴走を防止するという公益のためにこそ必要である、 ということを思い出すべきでしょう。
暗号化通信は現在のネット社会における不可欠な基礎リテラシですが、 それを自覚的・個的に用いれば、 あらゆるものがデータとしてやりとりされる世界での 「ディジタル五里霧」になります。 一人びとりがきちんと使いこなせるようになるべきだと考えます。
無論、暗号化可能な「データ」に固執するよりも、 そもそも謎と秘密の経路によってしか伝達しえない、 すなわち「データ」などにはなりえない、 例えばサルサやメレンゲのパートナワークの身体性を磨き抜く方が、 よりダンサ向きで、 より深い「抵抗運動」になることはいうまでもありません。