GnuPG for Windows ― gpg-agent について

no extension
  1. インストール編
  2. gpg-agent について (← イマココ)

gpg-agent

gpg-agentGnuPG の中核コンポーネントで,秘密鍵の管理1 を行い一定期間キャッシュする。 gpg-agentgpg, gpgsm, gpgconf, gpg-connect-agent といったコンポーネントから常駐プロセスとして起動されお互いに通信を行う2

gpg-agent が稼働中かどうかは gpg-agent を引数なしで起動すれば分かる。 以下は既に起動している場合。

$ gpg-agent
gpg-agent[3996]: gpg-agent running and available

gpg-agent が稼働していない場合は

$ gpg-agent
gpg-agent[9552]: no gpg-agent running in this session

などと表示される。

手動で gpg-agent を起動する場合は以下のコマンドで起動する。

$ gpg-connect-agent /bye
gpg-connect-agent: no running gpg-agent - starting 'C:\path\to\GnuPG\bin\gpg-agent.exe'
gpg-connect-agent: waiting for the agent to come up ... (5s)
gpg-connect-agent: connection to agent established

逆に gpg-agent を手動で停止したい場合は

$ gpg-connect-agent killagent /bye
OK closing connection

とすれば安全に停止できる。

Pinentry

Pinentry はパスフレーズ3 やスマートカードの PIN コードを入力する際に gpg-agent から呼び出される。 Windows 版では Pinentry プログラムとして pinentry-basic.exe が同梱されている。 同等の機能を持つものであれば他のプログラムと差し替えることもできる。

gpg--batch (または --pinentry-mode loopback)オプションとパスフレーズ指定オプション(--passphrase, --passphrase-fd, --passphrase-file)をセットで指定している場合は Pinentry を迂回できることがある(--quick-gen-key コマンドの場合など)。

gpg-agent のオプション

gpg-agent のオプションは GnuPG ホームディレクトリ4 直下にある gpg-agent.conf ファイルで設定する。 設定は以下の様なフォーマットで行う。

default-cache-ttl 600
max-cache-ttl 7200

gpg-agent.conf ファイルで使いそうなオプションを以下に挙げる。

オプション名 内容
log-file ログの出力先をフルパスで指定する。 挙動をチェックしたい場合など
default-cache-ttl 直前にアクセスしたキャッシュ・エントリの有効期間を秒単位で指定する。 既定値は 600
max-cache-ttl キャッシュ・エントリの有効期間の最大値を秒単位で指定する。 アクセスの有無にかかわらずこの期間が過ぎるとキャッシュがクリアされる。 既定値は 7200
pinentry-program 独自に Pinentry プログラムを指定する場合はここにフルパスで指定する
pinentry-timeout Pinentry プログラムの表示時間を秒単位で指定する。 既定値は 0 (タイムアウトなし)

他にも,鍵生成時にパスフレーズの文字種や最小文字長を指定したり,パスフレーズの有効期間(期間が過ぎると警告が出るらしい)を設定できたりするようだ。 オプション項目について詳しくははマニュアル(英語)を参照のこと。

PuTTY with gpg-agent

PuTTY は Windows 用の SSH クライアント兼ターミナル・エミュレータである。 PuTTY には Plink と呼ばれるコマンドラインベースの SSH 接続ツールがあり,他ツール(例えば Git for Windows)と連携できるようになっている。 さらに PuTTY には Pagent と呼ばれるエージェントツールもあり,認証用の秘密鍵をキャッシュすることができる。

今回は Pagent を gpg-agent で置き換えることを考える。

gpg-agent のオプション

gpg-agent.conf ファイルに以下のオプションを追加する(enable-putty-support 以外は任意)。

オプション名 内容
enable-putty-support Pagent プロトコルを有効にする
default-cache-ttl-ssh 直前にアクセスしたキャッシュ・エントリの有効期間を秒単位で指定する。 既定値は 1800
max-cache-ttl-ssh キャッシュ・エントリの有効期間の最大値を秒単位で指定する。 アクセスの有無にかかわらずこの期間が過ぎるとキャッシュがクリアされる。 既定値は 7200

設定を保存したら gpg-connect-agent を使って gpg-agent を再起動する。

$ gpg-connect-agent killagent /bye
OK closing connection

$ gpg-connect-agent /bye
gpg-connect-agent: no running gpg-agent - starting 'C:\path\to\GnuPG\bin\gpg-agent.exe'
gpg-connect-agent: waiting for the agent to come up ... (5s)
gpg-connect-agent: connection to agent established

なお, GnuPG の各コンポーネントは必要に応じて自動的に gpg-agent を起動するので問題ないのだが, PuTTYGnuPG と連動しているわけではないため, PuTTY 起動時に gpg-agent が起動していない状況もありうる。 そこで, Windows ログイン時に gpg-connect-agent を使って gpg-agent を起動しておくことをお薦めする。

SSH 鍵のインポート

SSH 鍵のインポートには2通りの方法あるようだが,今回は簡単な方でいく5

鍵ファイル(ここでは id_rsa.PPK とする)を Pagent で開く。 ファイルの関連付けがされている場合はエクスプローラから該当の PPK ファイルをダブルクリックすればいい。 そうでない場合は以下のコマンドで PPK ファイルを開く。

$ pageant.exe id_rsa.PPK

すると Pagent のプロンプトが1回, gpg-agent のプロンプトが2回表示され,都合3回パスフレーズを入力させられる。

Pagent
Pagent
GnuPG Pinentry (1)
GnuPG Pinentry (1)
GnuPG Pinentry (2)
GnuPG Pinentry (2)

これで秘密鍵が private-keys-v1.d フォルダに格納される。 また sshcontrol ファイルが作成され,インポートした鍵の情報が書き込まれる。

# List of allowed ssh keys.  Only keys present in this file are used
# in the SSH protocol.  The ssh-add tool may add new entries to this
# file to enable them; you may also add them manually.  Comment
# lines, like this one, as well as empty lines are ignored.  Lines do
# have a certain length limit but this is not serious limitation as
# the format of the entries is fixed and checked by gpg-agent. A
# non-comment line starts with optional white spaces, followed by the
# keygrip of the key given as 40 hex digits, optionally followed by a
# caching TTL in seconds, and another optional field for arbitrary
# flags.   Prepend the keygrip with an '!' mark to disable it.

# RSA key added on: 2016-03-10 21:24:32
# MD5 Fingerprint:  56:ff:fd:60:38:a1:7a:44:0c:37:86:90:94:8d:7f:6a
F65BB98767E88930612C6EABC4D4918E2A573903 0

この F65B... の長ったらしい数字列は keygrip と呼ばれる鍵の識別子で OpenPGP の鍵 ID とは異なるもののようだ6

これで鍵のインポートができたので PuTTY で実際に SSH 接続してみると

GnuPG Pinentry (3)
GnuPG Pinentry (3)

とプロンプトが表示された。 めでたし!

Git for Windows との連携

Git for WindowsPuTTY を連携するには,環境変数 GIT_SSH に Plink へのフルパスをセットする。

setx GIT_SSH=C:\path\to\PuTTY\plink.exe

一方,リポジトリの .git\config ファイルには PPK ファイルの場所をセットする。

[remote "origin"]
    puttykeyfile = C:/path/to/PuTTY/id_rsa.PPK

この状態で git fetch または git push を行うと Plink 経由で gpg-agent にリクエストが発生する。

Windows 版 gpg-agent は OpenSSH と相性が悪い?

gpg-agentOpenSSHssh-agent と置き換えることもできる7gpg-agent への SSH 鍵のインポートには ssh-add を使うのだが, Windows 環境では上手く動かない。 どうやらファイル・ディスクリプタ S.gpg-agent.ssh が上手く機能しないようだ。

MSYS28PowerShell 用OpenSSH で試してみたのだが,いずれも上手くいかなかった。 MSYS2 版については MSYS2GnuPG を使えば上手くいくのかもしれないが,面倒なので試してない。 今後,試す機会があればここに追記する。

参考になる(かもしれない) Web ページ


  1. 前回も書いたが, classic version と現行バージョンでは鍵(特に秘密鍵)の管理の仕方が異なるため両者を混在させる場合は注意が必要である。 Classic version で作成した鍵を現行バージョンにも反映させたいのであれば gpg-v21-migrated ファイルを削除すると再度移行処理が走るらしい。 Classic version を使わなければならない状況(Linux などではパッケージ管理ツールがアプリケーションの証明用に GnuPG の classic version を使うことがある)でないのなら現行バージョンに一本化するほうがお勧めである。 [return]
  2. 現行バージョンでは gpg-agent が必須である。したがって,かつての --use-agent, --no-use-agent, --gpg-agent-info 各オプションは無効(ダミーオプション)になっている。また UNIX 互換プラットフォームで gpg-agent 利用する際は GPG_TTY 環境変数をセットする必要があるが, Windows では不要なためここでは割愛する。 [return]
  3. パスワード(password)とパスフレーズ(passphrase)の違いは,パスフレーズでは英数字以外に空白文字や記号が使え文字数の制限がないことにある。ちなみに OpenPGP の秘密鍵にはいかなる形でもパスフレーズを保持しない(S2K パラメータ情報は持っている)。 [return]
  4. Windows では, GnuPG ホームディレクトリの既定は %APPDATA%\gnupg となっている。これを変更するには GNUPGHOME 環境変数または --homedir オプションを使う。(前回を参照のこと) [return]
  5. 今回は PPK ファイルを直接読み込む方法をとったが, PPK ファイルから OpenSSH 形式にエクスポートし,それを更に X.509 形式に変換した後 gpgsm でインポートすることもできる。(参考: Convert keys between GnuPG, OpenSsh and OpenSSL[return]
  6. OpenPGP 鍵以外の鍵にも対応するためらしい。 OpenPGP 鍵の keygrip は --with-keygrip オプションを付けて鍵を表示すると見ることができる。ちなみに private-keys-v1.d フォルダにある秘密鍵のファイルは,この keygrip 値がそのままファイル名になっている。 [return]
  7. gpg-agent.conf ファイルに enable-ssh-support オプションをセットする。 [return]
  8. Git for Windows に同梱されている git bashMSYS2 である。 [return]