GPGによるコミットの署名

Posted on 2024/08/15

ToC

Verifiedが表示されない

これまでPyCharmを利用していたのですが、最近はVS Codeも並行して利用しています。
そうしたところ、VS CodeでGitHubにコミットした際にVerifiedという表示がコミットに対して付与されないので、少し気になって調べてみました。 どうやら、ローカルでTagやCommitに署名することによってGitHubで検証され、Verifiedの表示がされることがわかりました。
今回は、GitHubのドキュメントを参考にGPG署名設定方法を整理してみたいと思います。
(ある意味、ドキュメントをトレースしているだけとも言えますが….)

GitHubのVerified表示 (GitHubドキュメントより)

/posts/2024/08/img/image0_hudfe5e6515590b424a4b6930bdf31f727_68351_900x0_resize_lanczos_3.png

GPGコマンドの導入

まずは、GPGキーを作成してみたいと思います。
ターミナルでgpgコマンドを実行してみましたが、どうやらインストールされていませんでした。
早速、brewにて導入します。インストールが完了するとユーザーディレクトリ配下に.gnupgというディレクトリが作成されます。 この中に各種の設定ファイルが登録されることになります。 ひとまず、手順に従ってGPG キーの有無を確認してみますが、当然ながらキーは存在していません。

$ brew install gnupg
〜 インストールの出力 〜

$ gpg --help
gpg (GnuPG) 2.4.5
libgcrypt 1.10.3
〜 各種ヘルプの表示 〜

$ gpg --list-secret-keys --keyid-format=long
gpg: directory '/Users/octcat/.gnupg' created
gpg: /Users/octcat/.gnupg/trustdb.gpg: trustdb created

新しい GPG キーを作成

新たにGPGキーを作成してみます。 gpgコマンドでは、RSA, ELG, DSA, ECDH, ECDSA, EDDSAの各種のアルゴリズムをサポートしています。GitHubでは、これらすべてをサポートしていました。なお、今回はrsa4096にて秘密鍵を作成することにします。
コマンドを実行すると名前 メールアドレス パスフレーズの入力があり、正しく入力されるとキーが作成されます。
その後に、GPG キー ID を指定してPGP PUBLIC KEYを出力します。

$ gpg --default-new-key-algo rsa4096 --generate-key
Real name: octcat
Email address: octcat@example.com
〜 パスフレーズのインタラクティブ入力 〜

$ gpg --list-secret-keys --keyid-format=long
[keyboxd]
------------------------------------
sec   rsa4096/ABCDEFGHIJKLMN 2024-08-15 [SC] [expires: 2027-08-15]
      ABCDEFGHIJKLMNOPQRSTUVWXYZ
uid                          [ultimate] octcat <octcat@example.com>

$ gpg --armor --export ABCDEFGHIJKLMN
-----BEGIN PGP PUBLIC KEY BLOCK-----
xxxxxxxx
xxxxxxxx
-----END PGP PUBLIC KEY BLOCK-----

GPGの公開鍵をGitHubに設定

GitHubのSettings > SSH and GPG Keys の画面を開きます。 Add new GPG keyをクリックすると、GPGのキーを登録する画面が表示されます。この画面にて、新しいGPGの公開鍵を登録します。
登録にはGPG Keyを識別するタイトルPublic Keyを設定して、追加ボタンをクリックするとGitHubへの公開鍵登録が完了します。 なお、確認のために登録時には、2要素認証チェックがありました。

/posts/2024/08/img/image1_hu0acc6d0bc5b0e99290fc9010a39a9dc2_47448_500x0_resize_lanczos_3.png

Gitのコミットの署名をする設定

ここまでくればあと少しです。
Gitでのコミット時にGPGの署名を行う設定を行います。Gitの下記の2つのコマンドを実行することで設定されます。

$ git config commit.gpgsign true
$ git config user.signingkey ABCDEFGHIJKLMN

あとはVS CodeでCommitして、GitHubにPushすれば、めでたくVerifiedの表示がされるようになります。
「めでたし、めでたし」と、思ったのもつかの間、、、

あれっ… また、コミットできない

改めてVS Codeからコミットを実行してみるとエラーが表示されて、うまく動かなくなってしまいました。

error: gpg failed to sign the data
fatal: failed to write commit object

ネット上をウロウロと探し回ってみたところ、どうやらパスフレーズの入力が関係しているようです。
パスフレーズの入力をサポートするpinentryというソフトウエアを利用することが良いようです。 inentry-macのインストール後にGPGの設定ファイルへの書き込みを実施して、gpg-agentを再起動します。

brew install pinentry-mac

echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

再度、コミットを実行してみると、先ほどまではエラーを繰り返していましたが、今度はコミットが前に進みます。 pinentryのダイアログが表示されますので、こちらにPGPのパスフレーズを入力します。

今度は、無事うまくコミットができたようです。
しばらく、時間が経過しても大丈夫そうですので、このやり方が正しいようです。

/posts/2024/08/img/image2_hu8fb8931501766db52a7e5dd34ddff719_98313_500x0_resize_lanczos_3.png

なお、入力したPGPのパスフレーズは、MacのKeyChainのログインの項目に保存されています。
GnuPGと検索すると対象を見つけることができます。

ちょっと苦労しましたが…

GPG自体も初めてさわったので、よくわからないことも多かったのですが、GPGチートシートの中に記載のあったコマンドを活用することで、秘密鍵のエクスポートなども勉強できました。これで、信頼されたコミットができます。
ありがとうございます。

ちなみに、GPGとはGNU Privacy Guard の略称のようです。
途中でPublic Keyのヘッダ部分がPGPとなっていて、一瞬GPGの間違い?と思ったのですが、GPG自体がPretty Good Privacy(OpenPGP)の別実装のようですね。(だからなんだ…)


参照