Skip to content

GPG鍵束の復旧

カーネルパニックが起きて再起動した後、GPGがエラーを吐いて使えなくなった。

Terminal window
$ git commit -m 'wip'
error: gpg failed to sign the data:
gpg: keydb_search failed: Invalid argument
gpg: skipped "2D9B751B97D95DFA": Invalid argument
[GNUPG:] INV_SGNR 0 2D9B751B97D95DFA
[GNUPG:] FAILURE sign 134250544
gpg: signing failed: Invalid argument
fatal: failed to write commit object
$ gpg -k
gpg: keydb_search_first failed: Invalid argument

public-keys.d/pubring.db はsqlite3データベースなので、これ自体が壊れている場合は以下のコマンドで復旧できる可能性がある。

Terminal window
cd $GNUPGHOME/public-keys.d
sqlite3 pubring.db .recover | sqlite3 new.db

DBは破損しているけど鍵ファイル自体が残っている場合は手動で復元する。まずは壊れたDBをリネームしておく。ロックファイルはただの空ファイルなので消せばいい。

Terminal window
cd $GNUPGHOME/public-keys.d
mv pubring.db o.db
rm pubring.db.lock

次にマスターキーのバックアップからマスターキーを復元する。ここでも手順は書くがGPG鍵の管理が詳しい。

Terminal window
$ gpg --import secret-key.asc
$ gpg --edit-key --expert C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81
gpg> trust

マスターキー以外にも秘密鍵があるなら取り込んでおく。

Terminal window
$ ls private-keys-v1.d/
8D5C126AA9B96D38590B92146BFCDF3FEB699318.key
BD461A92F8D624C4522D8A12757CCDEE37799A69.key
D2800BDE5ACCA5F66DD5478C40408331BCCEE037.key

3つ存在しているが、このうち1つはマスターキーの秘密鍵なのでそれ以外を取り込む。ここでは 8D5C126AA9B96D38590B92146BFCDF3FEB699318 を取り込む例を示すが、だいたい同じ手順になる。GitHubにGPG鍵を登録するで示したようにGitHubから取り込んでもいい。

Terminal window
$ gpg --edit-key --expert C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81
gpg (GnuPG) 2.4.7; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec ed25519/1A3BB38A4BC27A81
created: 2025-03-17 expires: never usage: C
trust: unknown validity: ultimate
[ultimate] (1). KADOTA, Kyohei <lufia@lufia.org>
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)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
(14) Existing key from card
Your selection? 13
Enter the keygrip: 8D5C126AA9B96D38590B92146BFCDF3FEB699318
Possible actions for this ECC key: Sign Authenticate
Current allowed actions: Sign
(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q
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 years
Key is valid for? (0) 3y
Key expires at Sun Apr 30 13:17:29 2028 JST
Is this correct? (y/N) y
Really create? (y/N) y
sec ed25519/1A3BB38A4BC27A81
created: 2025-03-17 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/209D69BD8ED702E2
created: 2025-05-01 expires: 2028-04-30 usage: S
[ultimate] (1). KADOTA, Kyohei <lufia@lufia.org>
gpg> save

これでマスターキーの秘密鍵は不要になるので消す。

Terminal window
gpg-connect-agent 'DELETE_KEY D2800BDE5ACCA5F66DD5478C40408331BCCEE037' /bye

Gitのコミットに本人確認の署名をするで設定している場合は、再構築すると鍵のIDが変わるので user.signingkey も変更する。

これで問題がなければバックアップを消す。

Terminal window
cd $GNUPGHOME/public-keys.d
rm o.db