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
gpg-agentからSSH鍵を削除する
$ vim ~/.gnupg/sshcontrol ### 適当なエディタでsshcontrolを開く
### 削除したいSSH鍵のkeygripを削除する。あるいは行頭に!を追加する。
GPG鍵をSSH鍵として使用する場合のみならず、 ssh-add
で追加したSSH鍵もこの方法で保存される。 ssh-add -d
は Identity 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
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の適当な位置に貼り付ける。
参考文献
- [gnupg_faq-no_default_of_rsa4096] https://www.gnupg.org/faq/gnupg-faq.html#no_default_of_rsa4096
- [hatsusato] https://gist.github.com/hatsusato/1d5f0267bc9d02bb24c60bd7acc5a59a
- [joemphilips] http://joemphilips.com/post/gpg_memo/
- [archwiki-gpg] https://wiki.archlinux.jp/index.php/GnuPG
- [riseup-bestpractices-set_calendar] https://riseup.net/en/security/message-security/openpgp/best-practices#set-a-calendar-event-to-remind-you-about-your-expiration-date
- [stackexchange-how_to_delete_subkey] https://superuser.com/questions/1132263/how-to-delete-a-subkey-on-linux-in-gnupg
- [stackexchange-import_secret] https://unix.stackexchange.com/a/392355
- [man-gpg_agent]
man gpg-agent
- [qiita-macos_gnupg_ssh] https://qiita.com/sira/items/d61caf237fed95090455
- [man-gpg]
man gpg
- [stackexchange-gpg_delete_ssh_key] https://unix.stackexchange.com/questions/185393/gpg-agent-doesnt-remove-my-ssh-key-from-the-keyring
- [git-gpg] https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E4%BD%9C%E6%A5%AD%E5%86%85%E5%AE%B9%E3%81%B8%E3%81%AE%E7%BD%B2%E5%90%8D
- [stackoverflow-autosign] https://stackoverflow.com/questions/10161198/is-there-a-way-to-autosign-commits-in-git-with-a-gpg-key
コメント
nani ga kaitearu ka ga wakaranai