GPG で公開鍵を他者と交換して署名する手順
GPG の公開鍵暗号で他者と暗号化された情報のやり取りをする場合などで必要になる, 互いの公開鍵を交換して署名する手順を説明します.
交換しただけではその公開鍵を使うことはできないので, 署名ということをしなくてはいけません.
今回は公開鍵と秘密鍵の鍵ペアが必要になりますので, まだ鍵ペアを生成していなくてどのように生成するのかお知りになりたい方は “新しい GPG 鍵ペアを生成する手順” を参考にしていただけたらと思います.
まずは公開鍵を相手と交換する方法から説明します.
公開鍵を相手と交換する場合, 基本的に二通りの方法があります.
手作業で交換する方法と鍵サーバーを使って交換する方法です.
手作業で交換する方法は, エクスポートした公開鍵を相手に届けるためにメールや USB メモリなどの媒体が必要になります.
一方の鍵サーバーを使って交換する方法は, 鍵サーバーを介して自身の公開鍵をアップロードして, 相手が自身の公開鍵をダウンロードするという仕組みなのでより簡潔に交換することができます.
なので今回はより実用性の高い鍵サーバーを使って公開鍵を交換する方法を説明したいと思います.
説明で使用する GPG のバージョンは 2.2.6
になります.
鍵サーバーを介して公開鍵を交換する
まずは使う鍵サーバーを設定したいと思います.
鍵サーバーはいくつかあるのですが, 主要なものに MIT の hkp://pgp.mit.edu
があり, それを選んでもいいのですがあくまで鍵サーバーというのは一つ一つのサーバーなので, 万が一ダウンしたときに一時的に使えなくなる可能性があります.
そこで一つ一つの鍵サーバーを集めることによって信頼性を保証してくれる鍵サーバープールというものが存在しますので, 鍵サーバーより鍵サーバープールを設定されることをおすすめします.
鍵サーバープールもいくつかありますが, 暗号化されて安全な接続ができる hkps プロトコルをサポートした hkps://hkps.pool.sks-keyservers.net
がおすすめです.
なので GPG の設定ファイル ~/.gnupg/gpg.conf
を開いて設定します.
そのファイルがない方は次のコマンドで作成できます.
touch ~/.gnupg/gpg.conf
chmod 600 ~/.gnupg/gpg.conf
そしたら次の 1 行を加えます.
keyserver hkps://hkps.pool.sks-keyservers.net
これでその鍵サーバープールをデフォルトで使えるようになりした.
その鍵サーバープールを使うために以前は sks-keyservers.netCA.pem
という証明書が必要だったのですが, GPG の 2.1.11
からその証明書がデフォルトで有効になったのでその証明書をインストールする必要がなくなりました.
では鍵サーバーを使う準備ができたので, その設定した鍵サーバーに公開鍵を送信する方法を説明したいと思いますが, その前に次のことに注意していただきたいです.
- 一度鍵サーバーに送信した公開鍵は二度と削除することはできず永久的に登録されることになる.
- 公開鍵のユーザー ID に設定したメールアドレスは世界中の人に見られるので, 願わずともスパムメールが送られて来る.
以上のことに留意された上で, 設定した鍵サーバーに自身の公開鍵を送信するため--send-keys
コマンドにその公開鍵の鍵 ID もしくは指紋を指定します.
gpg --send-key "your_keyid"
指紋でも送信できます.
gpg --send-key "your_fingerprint"
次は鍵サーバーに登録されている相手の公開鍵をダウンロードしてインポートする方法を説明します.
鍵サーバーから相手の公開鍵をインポートするためには, その公開鍵の本当の指紋を知る必要があります.
本当の指紋を知る方法は, その公開鍵の本人に直接会って教えてもらう, 電話で教えてもらうという方法があります.
それ以外の方法でも, 入手する指紋が本当に本人のものであると保証できるならば大丈夫です.
大事なことはなりすましの余地がない方法で本人の公開鍵の指紋を入手できるかどうかということです.
本人のものであると保証できる指紋を入手できたら, 次の --recv-keys
にその入手した指紋を指定し, 鍵サーバーからその公開鍵をインポートします.
gpg --recv-keys "their_authentic_fingerprint"
指紋の代わりに鍵 ID を指定して公開鍵をインポートすることもできますが, 鍵 ID は指紋の最後の 8 桁もしくは 16 桁と正確性に欠き, 意図しない公開鍵がインポートされる恐れがあるので --recv-keys
で公開鍵をインポートする際は常に指紋を指定するべきです.
GPG のバージョンが 2.1
より前だと, --recv-keys
に指定した指紋と一致する公開鍵が必ずしも鍵サーバーから送られてこない場合があったため, インポートしてからその公開鍵の指紋が本当に指定した指紋と完全に一致するか検証する必要がありましたが, GPG のバージョンが 2.1
から指定した指紋と一致しない公開鍵が送られてきた場合, GPG が拒否してくれるようになったのでインポートしてから指紋を検証する必要がなくなりました.
インポートした公開鍵に署名する
本人のものであると保証できる指紋を --recv-keys
に指定してインポートした公開鍵は署名することができます.
署名とはその公開鍵は本当に本人のものであると自身が証明するものです.
なので署名に使われる主鍵には Certify の頭文字 C
が与えられていて, Certify は証明するという意味です.
署名するコマンドはいくつかあるのですが基本的に --sign-key
か --lsign-key
のどちらかが使われます.
--sign-key
はエクスポート可能な署名と言われ, 自身の署名が他の人に公開されます.
なので自身の署名が他の人に見られてもいい場合は --sign-key
で署名します.
もっと正確に言いますと署名とは自身の信用を表したもので, 今回は詳しく説明しないのですが GPG の Web of Trust と言う仕組みで重要な役割を持っています.
しっかり本人のものであると保証できる公開鍵に署名すれば Web of Trust の信用のネットワークに寄与することができるのですが, 逆にそうでない場合 Web of Trust 全体の信頼性, 価値を落としてしまいます.
なのである意味責任が伴った署名というのが --sign-key
です.
--sign-key
で署名する場合は, 本人のものであると保証できる公開鍵の指紋を指定して行います.
gpg --sign-key "their_authentic_fingerprint"
--sign-key
で署名し終わったら, その公開鍵は自身によって署名されたという情報を公にするため, --send-keys
にその署名した公開鍵の鍵 ID もしくは指紋を指定し, その公開鍵をサーバーに送り返します.
gpg --send-keys "their_keyid"
その送り返された公開鍵の所有者および, その公開鍵をインポートしていた他者は --refresh-keys
と言うコマンドを入力するまで自身によってその公開鍵は署名されたという情報を見ることができません.
もちろん自身も自身の公開鍵やインポートした公開鍵の署名情報を更新するために, --refresh-keys
を時々自ら入力する必要があります.
gpg --refresh-keys
これで --sign-key
で署名する一連の手順は完了します.
もう一方の --lsign-key
はエクスポート不可能な署名と言われ, 自身の署名は他の人に公開されません.
なので --send-keys
に --lsign-key
で署名した公開鍵の鍵 ID を指定してサーバーに送信しても自身の署名情報は送られず公になりません.
自身の署名がなんらかの理由で他の人に見られたくない場合に使用する署名方法です.
--lsign-key
の l は local の l で自身の PC 内のローカルな環境でのみ有効な署名という意味です.
--lsign-key
で署名する場合も同じように, 本人のものであると保証できる公開鍵の指紋を指定して行います.
gpg --lsign-key "their_authentic_fingerprint"
まとめ
互いの公開鍵を交換するには, 本人のものであると保証できる指紋を入手する必要があります.
本人のものであると保証できる指紋を入手しなくてはいけないというのは GPG の弱点の一つで, もし本人になりすました悪意を持った第三者の指紋をつかまされて公開鍵をインポートした場合, その公開鍵を使った情報のやり取りは中間者攻撃によって情報漏洩のリスクに晒されてしまいます.
公開鍵を交換する際には, そう言った攻撃者に狙われる隙, GPG の弱点があると言うことを知っていただければと思います.
そして本人のものであると保証できる公開鍵にのみ署名しなくてはいけません.
関連記事
新しい GPG 鍵ペアを生成する手順2018.03.31
GPG でファイルを暗号化, 復号化, 署名, 検証する方法2018.04.03
Homebrew で macOS に GNU コマンドをインストールする2018.07.25
GPG で複数の受取人で暗号化する時に --group オプションが便利2018.07.29
Ruby のクラスやメソッドのドキュメントを見れる ri コマンドが便利な件2018.09.08