Carpe Diem

備忘録

GPGでgitのcommitに署名する

概要

GitHubではMergeコミットなどで

f:id:quoll00:20190714123803p:plain

といったマークを見ます。これは署名されたcommitを示すものなのですが、

  • なぜ必要なのか
  • どうやったら署名できるのか

を今回説明します。

環境

  • macOS 10.14.5 Mojave
  • gpg 2.2.10

なぜ署名が必要か?

gitのコミットは

commit 91e8e61ee6601576e358201315b6624181529879 (HEAD -> refactor-chain, origin/refactor-chain)
Author: Junpei Tsuji <junpei.tsuji.ams@gmail.com>
Date:   Sun Jul 14 11:42:29 2019 +0900

    Fixed a bug

のようにAuther名やEmailが付きますが、これらは自分で設定可能です。
ということは他人の名前やEmailを設定してcommitすることもできるため、なりすましが可能です。

GitHub上ではcommitにそういったなりすましではないことを保証するための仕組みとして署名をしたらVerifiedマークが付くようになってます。

Signing commits - GitHub Help

GPG Suite

GPG周りの設定が手間にならないよう、 GPG Suite をインストールします。

インストール

f:id:quoll00:20190714111648p:plain

ただし注意としてGPG Mailは有料機能で1ヶ月トライアルとなっているので、カスタマイズで外します。

f:id:quoll00:20190714112128p:plain

チェックボックスをOFFにしてください。

f:id:quoll00:20190714112236p:plain

gpg-agent.confの修正

~/.gnupg/gpg-agent.confに以下を追記します。

pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac

pinentryはパスフレーズ等の入力ダイアログ群で対話的に行うためのツールです。

ref: pinentryってなんだ - Qiita

GPG鍵を生成

それでは鍵を生成していきます。
Generating a new GPG key - GitHub Help に沿って進めます。

$ gpg --full-generate-key

鍵の種類

鍵の種類の選択です。1RSAで。

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
あなたの選択は? 1

鍵長

次に鍵長の指定です。
GitHubは4096ビットを推奨してるので4096で。

RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 4096

鍵の有効期限

最後は鍵の有効期限です。
GitHubでも無期限でOKとあるのでそのままEnter。

鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)

名前、メールアドレス、コメント

確認画面でyを押すと、名前、メールアドレス、コメントを聞かれます。

Note: When asked to enter your email address, ensure that you enter the verified email address for your GitHub account. To keep your email address private, use your GitHub-provided no-reply email address.

とあるようにメールアドレスはGitHubに登録してあるメールアドレスを入力します。コメントは任意です。分かりやすいようGitHubとしておきます。

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: Junpei Tsuji
電子メール・アドレス: junpei.tsuji.ams@gmail.com
コメント: GitHub
次のユーザIDを選択しました:
    "Junpei Tsuji (GitHub) <junpei.tsuji.ams@gmail.com>"

鍵のパスフレーズ

次は鍵のパスフレーズを入力します。 f:id:quoll00:20190714113445p:plain

エントロピーの供給

するとセキュリティのため十分なエントロピープールがほしいと言われます。

たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。

christina04.hatenablog.com

で説明したやつですね。既に十分あればすぐに終わりますし、なければ指示通りマウスを動かしたりしてください。

完了

以上で完了です。

gpg: /Users/jun06t/.gnupg/trustdb.gpg: 信用データベースができました
gpg: 鍵XXXXを究極的に信用するよう記録しました
gpg: ディレクトリ'/Users/jun06t/.gnupg/openpgp-revocs.d'が作成されました
gpg: 失効証明書を '/Users/jun06t/.gnupg/openpgp-revocs.d/YYYY.rev' に保管しました。
公開鍵と秘密鍵を作成し、署名しました。

pub   rsa4096 2019-07-14 [SC]
      YYYY
uid                      Junpei Tsuji (GitHub) <junpei.tsuji.ams@gmail.com>
sub   rsa4096 2019-07-14 [E]

GitHub側の設定

GPG公開鍵の生成

先程のXXXX秘密鍵のIDなので、それを使って公開鍵を生成します。
忘れてしまったら以下のコマンドで表示できます。

$ gpg --list-secret-keys --keyid-format LONG
gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
/Users/jun06t/.gnupg/pubring.kbx
--------------------------------
sec   rsa4096/XXXX 2019-07-14 [SC]
      YYYY
uid                 [  究極  ] Junpei Tsuji (GitHub) <junpei.tsuji.ams@gmail.com>
ssb   rsa4096/ZZZZ 2019-07-14 [E]

以下で公開鍵を生成可能です。

$ gpg --armor --export XXXX
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----

この公開鍵をコピーしておいてください。

GPG公開鍵をGitHubに登録

https://github.com/settings/keys で登録します。

f:id:quoll00:20190714110242p:plain

右上のボタンをクリックし、

f:id:quoll00:20190714110234p:plain

先程の公開鍵を入力。

f:id:quoll00:20190714110405p:plain

するとこのようにGitHubで登録が完了します。

他人のメールアドレスでも作れちゃうのでは?

本人確認のための署名であるはずですが、これまでは全て自分で設定していました。
であれば他人の名前やメールアドレスを騙ってなりすましできてしまうのでは?と思います。

しかしGitHub上の悪意あるユーザのアカウントでは、他人のメールアドレスはVerifiedできていない(=メールアドレス確認ができない)ので、以下のように表示されます。

f:id:quoll00:20190714113745p:plain

今回検証のためtaro.yamada@gmail.comのアカウントのGPG鍵を用意しましたが、commitしてもverifyマークはつかない事が分かります。

f:id:quoll00:20190714114112p:plain

ローカル開発マシンの設定

gitconfig

gitで署名ができるように設定を行います。
先程の鍵IDをconfigに設定しておきます。

$ git config --global user.signingkey XXXX

また、GPGプログラムの指定をします。

$ git config --global gpg.program /usr/local/MacGPG2/bin/gpg2

.gitconfigは以下のようになるはずです。

[user]
        name = Junpei Tsuji
        email = junpei.tsuji.ams@gmail.com
        signingkey = XXXX
[gpg]
        program = /usr/local/MacGPG2/bin/gpg2

Commitを署名する

commit時に-Sを付けてあげます。

$ git commit -S -m "Fixed a bug"

すると以下のようにGPG鍵のパスフレーズ入力を求められます。

f:id:quoll00:20190714114344p:plain

チェックボックスでkeychainに保存しておけば最初だけで済みます。

動作検証

GitHubにpushしてcommitを見てみると

f:id:quoll00:20190714122621p:plain

このようにverifiedマークが付くようになりました。

ソース