備忘録的なもの

PGP (GPG) ことはじめ - 概念編

PGP(GPG) を理解して使うために調べたこと。

PGP という名前とそういう仕組みがあること自体は認識していて、 Linux を使ってる中で触れることもあった。 ただ正しく理解して使っているかというとかなり怪しく、 都度ググって継ぎ接ぎの理解でとりあえず使っているくらいの感じだった。

そうではなくて、大枠というか概念的な部分からちゃんと理解して使いたいと思ったので 改めて調べて自分の理解や基本的な使い方を整理する。

書いてる途中で PGP (GPG) における概念的な理解の整理と GPG の使い方がごっちゃになり、書き難くなってしまったので2本に分けている。 今回はその内の PGP の理解をまとめた方になる。 今回調べた内容を忘れてしまったとしても、分けておいた方が見返しやすいだろうという意図もある。

また本文に関する補足として、秘密鍵と公開鍵、暗号化と復号、署名と検証といった公開鍵暗号の基本的な概念の部分や、 PGP 内での暗号化等の各処理における秘密鍵やハッシュ関数を使った処理の流れといった部分は省略している。

概要

ひとまず PGP ( Pretty Good Privacy ) の概要。

PGP はデータの暗号化/復号や、データへの署名/検証を行う暗号ソフトウェアの一つ。

「秘匿通信の実現」と「通信相手の認証」を主な目的として作られたもので、 そのために色々な技術を使って実現されている公開鍵基盤と呼ばれるものの一種になる。

  • 対象暗号
  • 公開鍵暗号
  • 一方向ハッシュ関数
  • データ圧縮

PGP はデータ(典型的にはファイル)の暗号化/復号 1 といった場面で独立したソフトウェアとして使うこともできるが、 他のソフトウェアと連携して使われていたりもする。 代表的なものでは、メールクライアントと連携してメールの暗号化に使われていたり、 パッケージマネージャと連携してネットワーク越しにダウンロードしてきたパッケージが正しいものかどうかの検証に使われたり、といった感じ。

PGP、OpenPGP、GnuPG の関係について

PGP を調べているとまず出てくる以下3つの関係について。

  • PGP
  • OpenPGP
  • GPG, GnuPG ( GNU Privacy Guard )

まず、1991年にアメリカで開発・公開された暗号ソフトウェアが PGP 、 それがアメリカの輸出規制を回避するための紆余曲折を経て 1998年にオープンな仕様として標準化されたものが OpenPGP 、 そして OpenPGP の仕様で実装されたソフトウェアの1つが GPG 。 という関係になっている。

実際にソフトウェアとして使われることが多いのは GPG ではあるが、 オリジナルの PGP もそれはそれで存続しており、これを書いてる時点ではブロードコム社のシマンテックブランドで提供されている。

PGP と GPG は別のソフトウェアではあり互換性の問題もあるらしい 2 が、 概念や機能がほぼ共通であることや、毎回 PGP と OpenPGP と GPG を厳密に表現すると冗長になるからか、 明確に GPG というソフトウェアを指す場合以外はまとめて PGP と呼ばれることが多い。 3

以降は仕組みや概念を指す場合は PGP 、具体的なソフトウェアを指す場面では GPG としている。

PGP の機能と鍵の役割

PGP の持つ機能としては主に以下の4つになり、 PGP の文脈で C、S、E、A といったものが出てきた場合、大抵これらのことを指している。

機能 内容
証明 (Certification) 別の鍵が本物であると証明するための機能(鍵に対して署名する機能)
署名 (Signing) データが本物であることを示すために電子署名を付与する機能(データに対して署名する機能)
暗号化 (Encryption) データを暗号化して特定の相手にのみ読めるようにするための機能
認証 (Authentication) 鍵を使って身元を証明する機能

4つの機能とは書いたが、実際にやっている処理としてはどれも公開鍵暗号における暗号化と復号、署名と検証で、 処理対象とするデータや状況によって4つに呼び分けていると言った方がしっくりくる。 そのため機能というよりは用途や使い方と言う方が近いのかもしれない。

PGP では自分の鍵を作成して各種操作を行うことになるが、 一般的には1本ではなく複数の鍵を作成して、上記の機能の内どの機能をどの鍵に持たせるかというのを設定して使うことになる。

鍵の機能を制限することでいくつか運用上のメリットがあるのだが、これについては後述の「主鍵と副鍵」で触れる。

信頼できる鍵かどうかを判断する仕組み

鍵の正当性について

PGP において「正当な鍵」というのがどういう意味かについて。

まず前提として PGP の鍵(公開鍵)は鍵自身が所有者の情報を持っている。 ただこれは鍵の作成時に自由に設定できるもので、言ってしまえば他人を騙って鍵を作る事も普通にできる。

そのため PGP のユーザは、何らかの方法で手に入れた鍵が「本当に自分が想定しているユーザが作った鍵なのか」を判断する必要があり、 このユーザが意図した所有者の鍵のことを PGP では「正当な鍵」と言う。

PGP における正当な鍵

正当な鍵かどうかを判断する方法としては色々あるが、典型的には以下のどれかのパターンで判断することになる。

  • そもそも鍵の改竄やなりすましが起きないであろう方法で鍵を交換する
    • 物理メディア(古くは FD 、現代なら USB メモリ等)を使って手渡しや郵送で鍵のやり取りをする
    • Keybase や Keyoxide みたいに別のサービスを通して鍵を手に入れる
    • 要するに、PGP とは別の仕組み(自分の目や公共サービス、Webサービス等)による認証を信頼する
  • 複数の場所で鍵を公開して受け取る側で比較確認する
    • 例えば公開鍵サーバ(後述)と自分のサイトの両方で同じ鍵を公開しておいて、受け取ったユーザに同じものである事を確認してもらう
    • 鍵そのものというよりはフィンガープリントで比較することが多い
    • 複数の場所(アカウント)を同時にクラッキングすることは難しいはず、ということを担保にする
  • 既に信頼関係にある第三者のお墨付きをもらう
    • これは「Web of Trust」で後述

とは言え、条件として厳しそうな攻撃方法 4 も含めると、正当な鍵かどうかを確実に判断することは難しく、 最終的には鍵を受け取ったユーザ自身がどの辺りで納得できるかという話にはなる。

Web of Trust について

前述した鍵の正当性を判断するために第三者のお墨付きを貰うという部分について。

鍵が正当なものであるかどうかは基本的に鍵を受け取ったユーザ自身が判断するものではあるが、 場合によってはユーザが直接判断できない場合もある。 そうした場合に信頼できる第三者を通じて鍵の正当性を判断する仕組みが存在しており、 PGP の4つの機能の中の証明 (Certification) により実現されている。

PGP における「証明」という機能についてもう少し触れておくと、 「ある鍵で別の鍵に対して電子署名を追加する」ことで、 「自身の鍵で署名した鍵を正当なものであると保証する」という意味合いの行為になる。

単純な例として、仮に PGP のユーザ A、B、C として図にするとこんな感じの関係になる。

単純な Web of Trust

こういった証明関係が増えると信頼関係のネットワークのようなものができ、これを PGP では Web of Trust と呼ぶ。

とはいえ、場合によっては上述のような判断にならない場合もある。例えば上記の関係を A から見たとして、

  • B の鍵は間違い無く本物だが、 B が PGP 初学者で証明するという行為の意味をちゃんと理解しているか怪しい
  • B の鍵は間違い無く本物だが、 B が保証しているものを全て信用できるほどの関係ではない

みたいなケースでは「鍵Bは本物だし、鍵Bの署名が鍵Cに付与されているが、鍵Cを本物とは判断しない」という判断もあり得る。

PGP ではこういった証明関係がある中でどの鍵を本物と判断するかをコントロールできる様にもなっていて、 それが鍵に設定する正当性と所有者信頼という 2つのパラメータになる。

鍵の正当性と鍵の所有者の信頼度

ここまでの話をまとめると PGP は鍵の信頼性について2つの観点を持っていることになる。

  • 鍵の正当性 ( Validity )
    • 自分の手元にある公開鍵の作成者が、自分が鍵の所有者と思っている実在の人物と一致するかどうか
  • 鍵の所有者の信頼度 ( Owner Trust )
    • 鍵が正当なものだったとして、その所有者の事をどこまで信頼できるか
    • 例として、以下のようなケースではそれぞれ信頼できるかどうかは変わってくるはず
      • PGP に精通した専門家が「この鍵は本物だ」と言っている場合
      • PGP を知って間もない素人が「この人は本物だ」と言っている場合
      • 毎日顔を合わせているような親しい友人が「この人は本物だ」と言っている場合
      • 会話したことも無い赤の他人が「この人は本物だ」と言っている場合

PGP ではこれらのパラメータとして、それぞれ以下のような値を持つ。 5

正当性の値 意味
Ultimately trusted 究極的に信頼する(自分の鍵)
Fully trusted 間違い無く本人の鍵だと判断した鍵
Trusted おそらく本人の鍵だと判断した鍵
Unknown or Untrusted 未知もしくは本人のものと判断できない鍵
所有者信頼の値 意味
Ultimately trusted 完全に信頼する(秘密鍵を持っている本人)
Fully trusted 常に信頼する
Marginally trusted 部分的に信頼する
Never trust this key 信頼しない
Not enough information 未知の鍵
No ownertrust assigned 未設定

ユーザがこれらの値を鍵に設定することで、 ユーザが直接正当な鍵と判断していない鍵についても PGP が設定値に基づいて正当な鍵かどうかを判定する仕組みになっている。

例として図にするとこんな感じ。

Web of Trust の例

ただ大事な点として、これらのパラメータをどういう基準でどの値に設定するかはユーザ各自に委ねられていて、 「〇〇だからこの値」というような正しい設定基準みたいなものは存在しない。 また、この Web of Trust の仕組みを使うかどうかも同様で、 所有者信頼の値を一切設定しない(=自分で直接正当性を確認した鍵しか信用しない)という運用方法も選択肢としては普通にあり得る。

この様に、 Web of Trust は鍵の正当性を判断するための手段のひとつでしかないということは認識しておく必要がある。

この辺りは PGP の「誰を信頼するかはユーザ自身が決定する」という思想の表れでもある。

主鍵と副鍵

仕組み上必須なわけではないが、 PGP の鍵は実際の運用上の都合から主鍵と副鍵 6 という複数本セットの構成で作成して使われることが多く、 最近の GPG では 7 構成を意識せずに鍵を作ると主鍵と副鍵の2本構成で作成される様になっている。

一般的に公開鍵暗号で用いられる鍵については、計算機の性能向上や暗号技術の脆弱性が発見されることによる鍵の危殆化、 鍵の運用をミスって秘密鍵を流出させてしまった、鍵のパスフレーズを忘れた、等の理由で入れ替えが必要になることがある。

そういった場合、 PGP では大まかに以下のような作業が必要になる。

  • 古い鍵の無効化(失効署名の作成)
  • 新しい鍵の作成
  • 失効署名と鍵の配布(データを送ったり公開鍵サーバへの登録等)
  • 配布した鍵が自分の鍵であることの証明

この中で鍵の運用上特にネックになるのが配布した鍵が自分の鍵であることを証明する部分で、 単に通信相手に鍵を送っただけでは受け取った側からしたら正当なものかどうかの判断が付かず、 改めて何らかの方法で鍵の正当性を確認する必要が出てくる。

そこで、鍵を管理するための主鍵と主鍵で証明された副鍵、という形で複数本の鍵を作成しておいて、 普段のやり取りには副鍵の方を使うという運用がよく行われている。

主鍵と副鍵の補足画像

こうすることで、仮に普段使っている副鍵を入れ替えることになったとしても、 新しい副鍵を作って相手に渡せば、それだけで通信相手は「以前やり取りしていたこの人の副鍵だから本物だ」という判断ができることになる。 8

また、鍵の入れ替え以外でも

  • 鍵の追加作成時にも自分の鍵であることを容易に証明できる
    • 例えば、暗号通信をしたいけど相手が ECC 鍵に対応してないから追加で RSA 鍵を副鍵として作成して使う、みたいなケース
  • 鍵の運用リスクの低減
    • 鍵管理に使っている主鍵の秘密鍵をローカルマシン内に置かず Yubikey や QR コード等でオフライン保管することで、秘密鍵の流出といった運用ミスを減らせる

等のメリットがある。

主鍵と副鍵に持たせる機能については、主鍵に証明機能が必須なこと以外は割と自由だが、

  • 主鍵 : 証明+署名
    • 副鍵 : 暗号化
  • 主鍵 : 証明
    • 副鍵 : 署名
    • 副鍵 : 暗号化

のどちらかの構成で作っておいて、必要に応じて副鍵を追加で作成していくというのがよくあるパターン。 (ちなみに GPG で鍵構成を意識せず作った場合は前者の構成になる)

公開鍵サーバ

PGP では鍵の交換をスムーズに行うために、公開鍵サーバというものが存在している。

元々他人の公開鍵を取り込む場合はファイル等で行うのが基本ではあったが、 毎回手動でやるのも手間なので、最近は公開鍵交換専用のサーバを介して公開鍵の取得や配布が行われることが多い。

公開鍵サーバに関しては何か集権的なものがあるわけではなくいろんな組織が運営している。 例としては以下のようなものがある。

サーバによっては鍵や失効証明の追加しかできなかったり(登録した鍵の削除ができない)、 特定のプロジェクトメンバーの鍵の公開専用のもの(メンバーでない個人が勝手に登録はできない)だったり、 機能はサーバによって若干の違いがある。 各サーバ毎に利用のガイドラインみたいなものがあるのかとかは調べて無いが、 個人で使う場合はとりあえず keys.openpgp.org を使うことが多い模様。

また、以前は鍵の証明関係の公開(前述の Web of Trust のサポート)にも一役買っていた様だが、 公開鍵サーバの汚染問題等もあってこの辺はオミットされる流れがある模様。 9

その他

PGP が使われる場面について

PGP は暗号化やデジタル署名が必要な場面で色々使える汎用性があり 通信経路によらず End-to-End で通信内容の安全性を担保できる仕組みではあるのだが、一般向けのサービスではそれほど広く使われていない。

というのも、PGP の仕組みを使って他人(の鍵)を信頼できるかどうかが、 Web of Trust で触れたようにユーザ各自の判断に依存した仕組みになっていることによる。

例えば、同じく公開鍵暗号を用いて通信相手を検証する仕組みとしてサーバ証明書の仕組みがあるが、 そちらでは鍵(サーバ証明書)の正当性を保証する第三者機関(認証局)が存在していて、 認証局が信用できるかの判断(ルート証明書の選定)もOSやブラウザのベンダーがユーザの代わりにやってくれている。 つまり、ユーザが各自で鍵の正当性を判断をしなくて良い仕組みになっている。 10

一方 PGP の場合は認証局やOS・ブラウザベンダーのような第三者機関が存在せず、 ユーザ各自が「この鍵は正当」「この鍵は正当」と全て自分で判断する必要がある。 公開鍵暗号にある程度の理解や興味がある人ならまだ良いが、そういった前提知識や興味も無い人に 鍵を正しく運用してもらうというのはいろんな意味で厳しい。 11

そのため一般的に広く使われてるサービスで PGP 前提になっているものはあまり無く、 実際 PGP で可能な暗号化や署名に関しても、別の方法が用いられていることが多い。

  • Gmail に代表されるメールでは SMTP over TLS が主流
  • 機密データのやり取りでも、オンラインストレージサービスの機能(サーバ証明書による暗号化やサービスの認証機構)でセキュリティを担保していることが多い

また、 PGP は鍵を比較的長期間に渡って安全に管理することが前提になっていて、 鍵運用にかかるコストと得られるメリットが釣り合って無いなんじゃないの、みたいな話も結構前からある様子。

ただ、そういった課題はありつつも今も使える仕組みではあり、前提知識や興味のある人やコミュニティであれば今も使われてはいる。

  • Git でのコミット署名
  • PGP で暗号化したメールのやり取り
    • PGP での暗号化に対応したメールクライアントは今もある(プラグインで対応してる場合もある)
    • Gmail の Web クライアントでもブラウザ拡張を入れれば使えたりする
  • SSH 用の鍵を GPG で管理するみたいな使い方もある

また、最近はプライバシーに関する意識的な話もあって、 E2EE なサービス(パスワードマネージャやメッセージングサービス等)も増えてきてたりはするらしいので、 そういった流れで注目される事もあるんだろうかというのは少し思ったりしている。

おわりに

調べつつ図を書いたりしながらまとめていると結構な時間が掛かったが、その分頭には入った気がする。

次は実際に GPG を使って鍵を作ったりファイルの暗号化したり、基本的な使い方をまとめる予定。

参考


  1. 復号という言葉については「暗号化に合わせて復号化の方が良い」「日本語表現として復号が正しい」の両方の説があるが、ここでは後者の 暗号化と復号 で統一している。 ↩︎

  2. オリジナルの PGP を触ったことは無いのと、調べてもイマイチ情報が見つからず正確には分からなかった。 古いバージョンだと使用可能なアルゴリズム等で差異があるらしいが、最近のバージョンだと問題にならないみたいな話もあった。 ↩︎

  3. 例えば、現在使われているのはほとんど GPG だと思うが、「GPG 鍵」と呼ばれることは少なく「PGP 鍵」と呼ばれることが多い。 他にも「 OpenPGP の仕組み」 とは言わず「 PGP の仕組み」といった感じ。 ↩︎

  4. 例えば、スパイ物のフィクションの様に変装して他人になりすまして鍵を交換する、鍵の入った郵便物をすり替える、 鍵を公開している複数の場所を同時にクラッキングする、等。 ↩︎

  5. 具体的な値については実際に GPG 等でコマンドを叩いて確認したわけではないので、 PGP と OpenPGP実装、バージョン等で差異があったりするかもしれない ↩︎

  6. 調べても漢字の読み方がはっきり分からなかったのだが、普通に「主鍵(しゅけん)」「副鍵(ふっけん)」で良いんだろうか。 ↩︎

  7. これを書いてる時点で自分が使っているバージョン( 2.4.4 )しか触ってないのでこう書いたが、最近ではない(ずっと前から)かもしれない。 ↩︎

  8. Web of Trust において主鍵から副鍵への署名(ある意味自己署名)の場合は特別な扱いになるらしい、ちゃんと確認できていないのでここは要確認。 ↩︎

  9. 5年前の記事を見ながら最近というのもアレだが ↩︎

  10. サーバ証明書の場合もユーザで鍵が信頼できるかどうかを個別にコントロールすること自体は可能だが、実際にやることはあまり無い(何かしらの一時的な回避策としてくらい) ↩︎

  11. 公開鍵暗号の基本的な部分や鍵を正しく運用する必要性を理解してもらったり、鍵運用の手間を許容してもらう、といった諸々 ↩︎