私的GPG逆引きリファレンス

GPG鍵の作成・管理、GPG秘密鍵と紐付いたSSH公開鍵の作成、 gpg-agentの利用、GitでのGPG鍵の利用などを一覧する。

想定環境

$ uname -srvmo
Linux 5.0.0-arch1-1-ARCH #1 SMP PREEMPT Mon Mar 4 14:11:43 UTC 2019 x86_64 GNU/Linux

$ gpg --version
gpg (GnuPG) 2.2.13
libgcrypt 1.8.4
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/anqou/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

master keyを作る

$ gpg --full-gen-keys

2048bitのRSA暗号で十分らしい[gnupg_faq-no_default_of_rsa4096]。 master keyの有効期限は無期限でいいらしい[hatsusato]gpg --gen-keys とすると無期限の設定ができない。作成中パスワードの入力を求められる画面でエントロピーがどうたらと書いてあるが、現環境では特に操作は必要なかった。 [joemphilips]には失効証明書を手動で作成する方法が書いてあるが、現環境では失効証明書は ~/.gnupg/openpgp-revocs.d/ 以下に保存されるので手動で作る必要はない。

実は暗号化用のsubkeyがここで勝手に作られるのだが、これには有効期限がついていない。仕方がないのでこれは後で削除して、別でsubkeyを作り直す。

以降 KEYID と書くとき、ここで生成したmaster keyや後で作成するsubkeyなどのkeyidを指定することを意味する。ハッシュ値(fingerprint)をそのまま書いても良いが、名前やメールの一部でも問題ない(場合がある)。 GPGはそのあたりに「寛容」らしい[archwiki-gpg]

公開鍵を一覧する

$ gpg --list-keys

ここで表示されるハッシュはfingerprint。

秘密鍵を一覧する

$ gpg --list-secret-keys

ここで表示されるハッシュはfingerprint。

subkeyを作る

暗号化・署名の片方のみができるsubkeyを作成する場合

$ gpg --edit-key KEYID
gpg> addkey
### RSA (暗号化のみ) を選択する。
### 2048bitを選択する。
### 鍵の有効期間として2yを選択する。
### パスワードを打ち込む。
### 諸々出力されてsubkeyができる。

gpg> save

その他のsubkeyを作成する場合

$ gpg --edit-key --expert KEYID
### 持たせたい機能を選択する。
### 以下同じ。

認証機能(Authenticate)はSSH鍵として使用する場合に必要らしい[archwiki-gpg]

subkeyには有効期間を定めておく。期限が近づいたら更新しなければならない。期限が切れたあとでも更新できるらしい[riseup_bestpractices_set-calendar]。勢い余ってsubkeyを消してしまうと、これで暗号化したファイルを復号化できなくなるらしい[archwiki-gpg]。どうせ忘れるのでスケジュールに追加しておくと良いらしい[riseup-bestpractices-set_calendar]

subkeyを削除する

$ gpg --edit-key KEYID
gpg> key 1  ### 何番目のキーを削除するのか指定する。ただし一番上のmaster keyは0番目と見なす。
### 削除したいキーに*印が付く。
### ちなみにすでに付いていた場合は*印が消える。すなわち非選択になる。

gpg> delkey
### 選択されていたキーが消えたリストが出る。

gpg> save

key KEYID とはできないので注意[stackexchange-how_to_delete_subkey]

master keyを取り除く

$ cp -r ~/.gnupg /where/you/wanna/save/keys ### バックアップを取る。
$ gpg --with-keygrip --list-key anqou ### master keyのkeygripを表示する。以下KEYGRIP。
$ rm ~/.gnupg/private-keys-v1.d/KEYGRIP.key ### master keyを削除。
$ gpg --with-keygrip --list-secret-key anqou   ### うまく消えていれば当該のmaster keyの部分に`sec#`と表示される。
$ rm ~/.gnupg/openpgp-revocs.d/KEYID.rev ### ついでに失効証明書も消しておく。

このやり方はGPG2.1以降らしい[joemphilips][hatsusato]でもこのやり方が紹介されている。失効証明書を削除しているサイトは見つからないが[archwiki-gpg]によれば「無効化証明書にアクセスできれば誰でも鍵を無効化して、利用できなくすることができてしまいます」とあるので、バックアップがあるなら消しておいたほうがよさそう[要出典]。

~/.gnupg 以外の場所にあるmaster keyを使用する

$ GNUPGHOME=/where/master/key/exists gpg ### 以下省略

要するに GNUPGHOME を指定すればよい。

fingerprintを表示する

gpg --fingerprint --fingerprint

オプションを2つ重ねることでsubkeyについてもfingerprintを表示する。

subkeyを失効させる

gpg --edit-key KEYID
gpg> key 失効させたいsubkeyの番号(1-origin)
gpg> revkey
gpg> save

動作未確認。重要なことはsubkeyには失効証明書などないということ。失効証明書はmaster keyのみに存在する。ただしsubkeyを失効させるときにはmaster keyが必要(多分)。

失効周りはテストしてないので詳細不明。一生使いたくない。

GPG鍵を他のマシンに移す

$ gpg --export KEYID > public.key
$ gpg --export-secret-key KEYID > private.key
### ここで他のマシンにpublic.keyとprivate.keyを移す
$ gpg --import public.key
$ gpg --import private.key
$ gpg --edit-key KEYID trust quit
### 「究極的に」信用する

[stackexchange-import_secret]より。最後のコマンドで鍵の状態を「不明」から「究極」にする。

gpg-agentにssh-agentの代わりをやらせる

.zshrc (乃至それに類するもの) に以下を追加。

export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $ ]; then
  export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

[archwiki-gpg]より。 ~/.gnupg/gpg-agent.conf を編集する必要は (これだけをやるためには)特に必要ない。

gpg-agent.conf のオプションである enable-ssh-support[man-gpg_agent]によると SSH_AUTH_SOCK 環境変数を設定するだけのようなので、このように手動で指定する場合は、おそらく必要ない。 また write-env-file は少なくとも2.2.13では意味を為さないオプションになっている。

これによって ssh-add を使用できるようになる。GPG鍵もSSH鍵として使用できる(後述)。鍵を確認する場合は ssh-add -l とすればよい。 ssh-agent とは異なり、一度追加してしまえば再度追加する必要はない。実際にSSH鍵を使用するときにパスワード入力を求められるのみである。

gpg-agentにSSH鍵として使用するGPG鍵を伝える

$ gpg --list-keys --with-keygrip ### 使用したいGPG鍵のkeygripを確認。以下KEYGRIP。
$ echo KEYGRIP >> ~/.gnupg/sshcontrol

~/.gnupg/sshcontrol にkeygripを書き込まなければGPG鍵をSSH鍵として使用することはできないらしい[qiita-macos_gnupg_ssh]

GPG鍵からSSH公開鍵を作成する

$ gpg --export-ssh-key KEYID! ### GPGを直接使用する場合

末尾の ! に注意。これを指定しない場合、指定したKEYIDのGPG鍵の内、認証機能を持つ最も最近に作成したsubkeyのSSH公開鍵を出力する[man-gpg]。すなわち認証機能を持つ特定のsubkeyのSSH公開鍵を作成したい場合は、まずそのsubkeyのfingerprintを取得した後、それをKEYIDとして指定し、最後にエクスクラメーションマークをつける必要がある。 subkeyのfingerprintは --fingerprint を二回重ねることで出力できるが、この表示では4桁ごとにスペースが入ってしまうため以下のようにして取り除く必要がある。

### subkeyの一部にXXXXを含むとする
$ gpg --fingerprint --fingerprint | grep XXXX | sed 's/ //g'
### 当該subkeyのfingerprintがスペース無しで出力される

なお gpg-agent にGPG鍵をSSH鍵として登録した後ならば ssh-add を使用しても確認可能:

$ ssh-add -L

ここで作成したSSH公開鍵を適当なサーバの ~/.ssh/authorized_keys に追加すればGPG鍵を用いてSSH認証を行うことができる。

ここで作成したSSH公開鍵はあくまでsubkeyに紐づくものであることに注意。 master keyとsubkeyを使い分けるメリットとして、subkeyが流失した際にsubkeyを失効させることで信頼を担保するというものがあるが、SSH認証では接続相手のSSH秘密鍵が失効しているかなどを検査しないため、失効手続きを行った後でも、流失したsubkeyでSSH認証が可能のはずである(未確認)。

gpg-agentをリロードする

$ gpg-connect-agent reloadagent /bye

[archwiki-gpg]より。

gpg-agentからSSH鍵を削除する

$ vim ~/.gnupg/sshcontrol ### 適当なエディタでsshcontrolを開く
### 削除したいSSH鍵のkeygripを削除する。あるいは行頭に!を追加する。

GPG鍵をSSH鍵として使用する場合のみならず、 ssh-add で追加したSSH鍵もこの方法で保存される。 ssh-add -dIdentity removed の表示が出るにも関わらず、 sshcontrol からは削除されないため、効果がないようである[stackexchange-gpg_delete_ssh_key]

gpg-agentへのパスワード入力方式を変更する(pinentry)

$ vim ~/.gnupg/gpg-agent.conf ### 適当なエディタでgpg-agent.confを開く
# PIN entry program
# pinentry-program /usr/bin/pinentry-curses
# pinentry-program /usr/bin/pinentry-qt
# pinentry-program /usr/bin/pinentry-kwallet
pinentry-program /usr/bin/pinentry-gtk-2

[archwiki-gpg]より。

GitにGPG鍵を追加する

$ git config --global user.signingkey KEYID

~/.gitconfig[user]signingkey の項が追加される。

Gitのcommit時に署名する

$ git commit -S

[git-gpg]より。常に署名したい場合は git config commit.gpgsign true とする。 これには普通 --global をつけないらしい[stackoverflow-autosign]

Gitのtag作成時に署名する

$ git tag -s v1.5

[git-gpg]より。

GitHubにGPG鍵を追加する

$ gpg --export --armor KEYID | pbcopy
### クリップボードにGPG公開鍵がコピーされる。
### GitHubの適当な位置に貼り付ける。

参考文献

コメント

  1. nininga より:

    nani ga kaitearu ka ga wakaranai