GPG鍵の管理
XDG Base Directoryにこだわりがある場合、GPGのホームディレクトリを変更するに従って設定しておくといい。
マスターキーの作成
Section titled “マスターキーの作成”対話モードでは以下のような流れとなる。後で書いているが基本はサブキーで運用するのでマスターキーの役割は証明(Certify)のみ持つようにする。
$ gpg --full-generate-key --expertPlease select what kind of key you want: (1) RSA and RSA (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (9) ECC (sign and encrypt) *default* (10) ECC (sign only) (11) ECC (set your own capabilities) (13) Existing key (14) Existing key from cardYour selection? 11
Possible actions for this ECC key: Sign Certify AuthenticateCurrent allowed actions: Sign Certify
(S) Toggle the sign capability (A) Toggle the authenticate capability (Q) Finished
Your selection? S
Your selection? Q
Please select which elliptic curve you want: (1) Curve 25519 *default* (4) NIST P-384 (6) Brainpool P-256Your selection? 1
Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n yearsKey is valid for? (0)このとき、GNUPGHOME ディレクトリを作成しておかないと以下のようなエラーで失敗するので注意が必要。
gpg: no writable public keyring found: Not found Key generation failed: Not found
また、対話モードが不便な場合、gpg —batch オプションを使うと非対話モードで実行することもできるらしい。
gpg --batch --full-generate-key gen-key.confgen-key.conf に記述する内容は公式のマニュアルを参照。
成功すれば、マスターキーの秘密鍵と公開鍵、それと鍵を失効するための失効証明書が追加される。失効証明書はマスターキーを紛失したときに使うもので、鍵があるなら必要ない。また、上では役割をCertifyのみとしたので存在しないが、ECC (sign and encrypt) を選んだ場合は暗号化用の鍵も一緒に作られる。
鍵のリストを表示
Section titled “鍵のリストを表示”gpg —list-keys (-k) または *gpg —list-secret-keys (-K)*コマンドを使う。
$ gpg --list-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------pub ed25519 2025-03-17 [C] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>
$ gpg --list-secret-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------sec ed25519 2025-03-17 [C] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>ここで出力されている C7BF… がマスターキーのID(fingerprint)と呼ばれる。—full-generate-key のとき署名のみを選んだので、マスターキーの秘密鍵と公開鍵の2つしか作られていないが、署名と暗号化を選んだ場合は追加で暗号化のためのサブキーも作られる。
$ gpg --list-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------pub ed25519 2025-03-15 [SC] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>sub cv25519 2025-03-15 [E] [expires: 2026-03-15]このときサブキーにはフィンガープリントが付いていないけれど、裏では存在している。—with-subkey-fingerprint オプションを付けるとサブキーも見れる。上の例と異なるが実行結果を以下に示す。
$ gpg --list-keys --with-subkey-fingerprint/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------pub ed25519 2025-03-17 [C] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>sub ed25519 2025-03-17 [S] [expires: 2027-03-17] 3236062EBAD2D501DE81BEAB2D9B751B97D95DFA—keyid-format=long オプションを付けるとサブキーの暗号アルゴリズム後ろに / で区切って鍵IDが出力されるけれど、これはKey IDといって単にフィンガープリントの末尾8バイトを抜き出したものになっている。末尾4バイトの形式もあるらしいが見たことはない。
secとかsubは何を意味するのか
Section titled “secとかsubは何を意味するのか”- sec: 秘密鍵(Secret key)
- ssb: サブキーの秘密鍵(Secret Subkey)
- pub: 公開鍵(Public key)
- sub: サブキーの公開鍵(Public Subkey)
- sec#: 秘密鍵だけど鍵が存在しない状態
SCとかEは何を意味するのか
Section titled “SCとかEは何を意味するのか”鍵が持っている役割のこと。
- S: Signing (署名)
- C: Certify (証明)
- E: Encrypt (暗号化)
- A: Authenticate (認証)
マスターキーをバックアップ
Section titled “マスターキーをバックアップ”普段使う環境に置いておくと危険なので、安全な場所にだけ置いておき必要になったら取り出したい。そこでまずはマスターキーの秘密鍵をバックアップする。公開鍵も含まれているらしいので、特に理由がなければ秘密鍵だけでよい。
今の時点では次のような鍵が存在しているはず。
$ gpg --list-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------pub ed25519 2025-03-15 [SC] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>サブキーは失っても再作成すれば困らないので、マスターキーの秘密鍵だけバックアップする。
gpg --armor --export-secret-keys -o secret-key.asc lufiaこれで secret-key.asc に PGP PRIVATE KEY BLOCK ヘッダを持つ鍵が出力されるので安全な場所に保管する。
[!Info] マスターキーの秘密鍵と書いたが、これは今の時点でマスターキーしか存在していないためそう表現している。しかしコマンド自体はサブキーも含めてすべての秘密鍵をエクスポートする。
下に書いたサブキーの秘密鍵だけエクスポートする項も関連する。
サブキーの追加
Section titled “サブキーの追加”GPGではサブキーを普段使いすると決めたので、ここではGitコミットの署名用にひとつ追加してみる。gpg —edit-key は user-id を要求するが、ユーザーIDはGnuPG - ArchWikiによると、鍵のフィンガープリント、メールアドレス、名前の一部などが使えるらしい。試した限りでは、おそらく大文字小文字も区別しない。
$ gpg --edit-key --expert C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81
gpg> addkey
Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (10) ECC (sign only) (12) ECC (encrypt only) (14) Existing key from cardYour selection? 10Please select which elliptic curve you want: (1) Curve 25519 *default* (4) NIST P-384 (6) Brainpool P-256Your selection? 1Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n yearsKey is valid for? (0) 1yKey expires at Mon Mar 16 01:45:11 2026 JSTIs this correct? (y/N) yReally create? (y/N) y最後に save を忘れると保存されない。逆に中止したい場合は quit とする。
gpg> saveこのコマンドは —quick-add-key でも代用できそう。また、パスフレーズはマスターキーと同じものが設定されるらしい。
マスターキーを取り除く
Section titled “マスターキーを取り除く”マスターキーを削除する方法はいくつか存在するようだった。例えば以下の3つではそれぞれ異なる方法で取り除いている。
簡単そうなのでKeygripを使う方法で取り除く。しかし上の記事に書かれている方法はファイルを直接消していたが、ファイルを直接扱うのも行儀が悪いと思うので別の方法を使う。
$ gpg --with-keygrip --list-secret-keys C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81sec ed25519 2025-03-17 [C] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81 Keygrip = D2800BDE5ACCA5F66DD5478C40408331BCCEE037uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>ssb ed25519 2025-03-15 [S] [expires: 2027-03-15] Keygrip = 0F24F14F7D40ECB9A02E680DDE9BF9392C1B5ED2
$ gpg-connect-agent 'DELETE_KEY D2800BDE5ACCA5F66DD5478C40408331BCCEE037' /byeこれで —list-secret-keys で sec# と表示され、この意味は秘密鍵が存在しない状態を表す。公開鍵の表示は変わらない。
$ gpg --list-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------pub ed25519 2025-03-15 [SC] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>
$ gpg --list-secret-keys/home/lufia/.local/share/gnupg/pubring.kbx------------------------------------------sec# ed25519 2025-03-15 [SC] C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81uid [ultimate] KADOTA, Kyohei <lufia@lufia.org>サブキーの秘密鍵だけバックアップ
Section titled “サブキーの秘密鍵だけバックアップ”ほとんどマスターキーと同じだがオプションが少しだけ異なる。
gpg --armor --export-secret-subkeys -o privatesubkeys.ascところで、—export-secret-keys にサブキーの秘密鍵も含まれるのだが、こちらは何が違うのか。これはマスターキーの秘密鍵を含むかどうかが異なるだけらしい。gpg —list-packets を使うとエクスポートされる内容が読めるけれど、マスターキーの秘密鍵がダミーになっている。
gpg --armor --export-secret-subkeys | gpg --list-packetsマスターキーの秘密鍵は厳密に管理するべきものなので、普段のバックアップはこちらを使えばいい。
失効証明書をバックアップ
Section titled “失効証明書をバックアップ”マスターキーがあれば後からでも失効させることが可能だが、バックアップしていても損はない。失効証明書はマスターキーを作成したとき $GNUPGHOME/openpgp-revocs.d 以下に作られるので、これをすべてコピーすればいい。
不要な鍵を削除
Section titled “不要な鍵を削除”公開鍵と秘密鍵の両方を消せば良いらしい。
gpg --delete-secret-keys 2D9B751B97D95DFAgpg --delete-keys 2D9B751B97D95DFAサブキーの場合は鍵IDの末尾に ! を使って自動選択の無効化が必要かもしれない。このとき公開鍵だけを削除することはできない。複数の公開鍵が同じ秘密鍵を共有していたとしても先に秘密鍵を消さなければならないので、公開鍵だけ消したい場合は秘密鍵をバックアップしておいて、公開鍵を消した後でバックアップから復元するなどの手順が必要になる。
cp 8D5C126AA9B96D38590B92146BFCDF3FEB699318.key bakgpg --delete-secret-keys 2D9B751B97D95DFA!gpg --delete-keys 2D9B751B97D95DFA!mv bak 8D5C126AA9B96D38590B92146BFCDF3FEB699318.keyマスターキーを復元
Section titled “マスターキーを復元”バックアップしておいたマスターキーの秘密鍵を鍵束にインポートする。
gpg --import secret-key.asc信用度を最高にする。
gpg --edit-key C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81
gpg> trustsec ed25519/1A3BB38A4BC27A81 created: 2025-03-17 expires: never usage: C trust: ultimate validity: ultimate[ultimate] (1). KADOTA, Kyohei <lufia@lufia.org>
Please decide how far you trust this user to correctly verify other users' keys(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu
Your decision? 5
gpg> save複数のユーザーIDを登録
Section titled “複数のユーザーIDを登録”PGP/GPGについての情報整理によると、—edit-key でメールアドレス等を追加できるらしい。
gpg --edit-key ID adduid鍵の生成で失敗する
Section titled “鍵の生成で失敗する”gpg コマンドを実行したとき、以下のようなエラーでエージェントと通信できず失敗する場合がある。
$ gpg --full-generate-keygpg: can't connect to the gpg-agent: No such file or directorygpg: agent_genkey failed: No agent runningKey generation failed: No agent runningこれはおそらく、GNUPGHOME を変更したときに gpg-agent.socket の変更が漏れているので、修正の後にユニットを再起動するといい。
マスターキーのパスフレーズを変更する
Section titled “マスターキーのパスフレーズを変更する”gpg —edit-key で編集を開始して、passwd コマンドで変更する。
$ gpg --edit-key <user-id>gpg> passwdgpg> save
gpg> quit同じ方法でサブキーのパスフレーズも変更できるらしいが試していない。
マスターキーの期限を変更する
Section titled “マスターキーの期限を変更する”gpg —quick-set-expire コマンドで変更できる。
gpg --quick-set-expire BF6A9F34814124AE28BD01597C63237ED4C24B72 0秘密鍵が消える
Section titled “秘密鍵が消える”GNUPGHOME を未設定のまま gpg コマンドを実行すると ~/.gnupg にファイルが作られてしまう。このディレクトリを安易に削除してしまうと、それ以降の gpg —list-secret-keys 等で秘密鍵が参照できなくなってしまう。
どうやらターミナルで GNUPGHOME を設定しただけでは、プライベートキーが ~/.gnupg へ入ってしまうらしい。再起動していないから gpg-agent に環境変数が渡っていない。