署名鍵の作成
Git コミット署名用の鍵を作成する。
鍵を作成するにあたって、すでに親となる鍵が作成されているものとする。(まだ作成してない場合は、鍵の作成とエクスポート/インポートの 「鍵署名用の鍵を作る」を見ながら主鍵を先に作っておく)
既に署名用の副鍵を作っている場合や、主鍵にデータ署名機能 ([SC]) を持たせている場合は、この手順を飛ばすことができる。
# コンピュータにインストールされている秘密鍵を確認
$ gpg -K --keyid-format LONG
/home/user/.gnupg/pubring.kbx
-------------------------------
sec ed25519/BF98EE21F2F9F048 2024-04-04 [C]
A360CEF20643088F3958CDECBF98EE21F2F9F048
uid [ultimate] foo@example.com
gpg --edit-key *KEYID*
コマンドを用い、副鍵を追加する。(最後に保存するのを忘れずに)
$ gpg --expert --edit-key BF98EE21F2F9F048
Secret key is available.
sec ed25519/BF98EE21F2F9F048
created: 2024-04-04 expires: never usage: C
trust: ultimate validity: ultimate
[ultimate] (1). foo@example.com
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) # <- Select
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
(14) Existing key from card
Your selection? 10
Please select which elliptic curve you want:
(1) Curve 25519 # <- Select
(3) NIST P-256
(4) NIST P-384
(5) NIST P-521
(6) Brainpool P-256
(7) Brainpool P-384
(8) Brainpool P-512
(9) secp256k1
Your 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 years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec ed25519/BF98EE21F2F9F048
created: 2024-04-04 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/02B2D9F670FD18C9
created: 2024-04-04 expires: never usage: S
[ultimate] (1). foo@example.com
gpg> save
Git のコミット時に署名する設定を行う
$ git config --global user.signingkey BF98EE21F2F9F048
$ git config --global commit.gpgsign true
下記の設定が追加されていれば OK。
$ cat ~/.gitconfig
[user]
signingkey = 02B2D9F670FD18C9
[commit]
gpgsign = true
テストを兼ねて、適当にリポジトリを作成し1つコミットを作成する。
コミット作成時にパスフレーズを尋ねられるようになるため、鍵作成時に設定したパスフレーズを入力する。問題なくコミットできれば完了。
┌───────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "foo@example.com" │
│ 255-bit EDDSA key, ID 02B2D9F670FD18C9, │
│ created 2024-04-04 (main key ID BF98EE21F2F9F048). │
│ │
│ │
│ Passphrase: _________________________________________________ │
│ │
│ <OK> <Cancel> │
└───────────────────────────────────────────────────────────────┘
公開鍵のエクスポート
コミットを共有する相手が署名を検証できるようにするには、署名した秘密鍵に対応する公開鍵を相手に渡しておく必要がある。
公開鍵をエクスポートする を参考にして公開鍵を出力し、鍵を相手に渡したり Github などにアップロードしたりできる。
トラブルシュート
gpg failed to sign the data が発生する
https://gist.github.com/paolocarrasco/18ca8fe6e63490ae1be23e84a7039374 に調査方法が記載されていたので、それを試す。
まず、GIT_TRACE=1
を設定して Git が何をしようとしているかを確認する。
$ GIT_TRACE=1 git commit -m "initial commit" --allow-empty
08:00:22.114351 git.c:455 trace: built-in: git commit -m 'initial commit' --allow-empty
08:00:22.116297 run-command.c:668 trace: run_command: gpg --status-fd=2 -bsau 02B2D9F670FD18C9
error: gpg failed to sign the data
fatal: failed to write commit object
自分の環境の場合、パスフレーズを求めるダイアログが表示されず失敗していたので、 export GPG_TTY=$(tty)
を設定してから再度 git commit をしたら正常にコミットできた。
$ export GPG_TTY=$(tty)
$ git commit -m "initial commit" --allow-empty
[master 43b460f] initial commit
export GPG_TTY=$(tty)
を .bashrc に書いておくのがセオリーらしい。
他にコミットが失敗することがある状況としては、指定された Key ID が見つからない、指定された鍵に [S] フラグが付いていない、などがある。