GitHubでのGPG
gitではGPG(Gnu Private Guard)を用いて、commitやtagにsignすることができます。GitHubでは、このsignを用いて認証を行い、認証が成功したものに関しては、verifiedというマークを付与します。
GitHubでの認証にはweb of trustは用いられず、単にcontributerのうちの誰かと認証されることによってのみ、認証は成功とみなされます。
鍵の生成
まず、鍵を生成します。
gpg --full-gen-key
ただ待っていると時間がかかるので、gpg --gen-keyが止まる件についてを参考に、対策してください。
次に、生成した鍵を確認します。署名に使うのは、pub keyでもsub keyでも構いませんが、sub keyの方が安心でしょう。
gpg --list-keys --keyid-format short
#pub rsa4096/C1356B8B 2019-01-28 [SC] [expires: 2020-01-28]
# 8E579C1DA2A96D755833A5B3A294B64FC3354B8B
#uid [ultimate] Hoge Fuga <hoge@example.com>
#sub rsa4096/A1279318 2019-01-28 [E] [expires: 2020-01-28]
上の場合、subkeyが署名に対応していない*ので、別のsubkeyを作ります。この時点で、subkeyが署名に対応している人は、GitHubに登録まで飛ばして構いません。
gpg --edit-key C1356B8B # pubkeyのID
gpg> addkey
gpg> save
addkeyを実行した時に、暗号の種類を聞かれますので、署名に対応したものを選んでください。
これを実行すると、新たなsubkeyが生成されます。
gpg --list-keys --keyid-format short
#pub rsa4096/C1356B8B 2019-01-28 [SC] [expires: 2020-01-28]
# 8E579C1DA2A96D755833A5B3A294B64FC3354B8B
#uid [ultimate] Hoge Fuga <hoge@example.com>
#sub rsa4096/A1279318 2019-01-28 [E] [expires: 2020-01-28]
#sub rsa2048/39D812AC 2019-01-28 [S] [expires: 2020-01-28]
今生成した鍵は、[S]と書いてあるので、ちゃんと署名に対応していますね。
GitHubに登録
pub keyをGitHubに登録します。
鍵のIDはC1356B8Bです。この鍵の中身を見るには、
gpg --armor --export C1356B8B # pubkeyのID
とします。
この内容をクリップボートなりにコピーして、GitHubページのAccount->Settings->SSH and GPG keysのGPS keysにペーストします。このとき、GitHubに登録されているメールアドレスに、鍵の生成時に入力したメールアドレスが含まれている必要があります。
以上で、鍵の登録は終わりです。
Commitに自動的にsignされるように設定
git config --global commit.gpgsign true
signにつかうkeyの指定
git config --global user.signingkey 39D812AC # subkeyのID
revoke(無効化)出来るようにしておく
秘密鍵のpassphraseを忘れてしまったり、秘密鍵を誰かに取られてしまうことって、よくありますよね。そんな時のために、鍵をrevokeする方法を事前に用意しておきます。
revoke用の鍵を用意する
gpg --gen-revoke --output <file> C1356B8B # pubkeyのID
これで、にrevoke用の鍵が生成されます。実際にrevokeするときは、
gpg --import <file>
で出来ます。ただし、これはローカル環境の設定変更に過ぎないので、これを他の人に告知する必要があります。
そのためには、GitHubに登録した鍵を消去します。って、revoke key要らないね。
というのは冗談で、そんなことをしたら過去に署名したcommitなりtagなりが全てunverifiedとなってしまいます。それを防ぐために、revokeが使えます。
revokeをすると、pub keyにrevokeをした日時が書き込まれます(多分)。その新しいpub keyで、GitHubに登録してある古いpub keyを置き換えることで、revokeをした日時以前の署名は有効に、それ以降の署名は無効に出来ます。
また、気づいたかもしれませんが、この方法だと全てのsub keyがrevokeされます。それでは不便という場合には、特定のsubkeyのみrevokeすることもできます。
特定のsubkeyをrevokeする
これは事前に行うことはできません。おそらく、事前に行う必要がないからです。というのも、全てのsubkeyをrevokeしたい時というのは、pub keyの秘密鍵を盗まれた時か、pub keyのpassphraseを忘れた時で、後者の場合は事前にrevokeを作っておく必然性があります。ちなみに、sub keyのrevokeには、sub keyのpassphraseは必要ありません。
gpg --edit-key C1356B8B # pubkeyのID
gpg> key n # subkeyの表示順
gpg> revkey
gpg> save
signする意味
多要素認証
GitHubにpushするためには、ログインが必要です。じゃあ、それで認証になっているのではないかという話。これは、多要素認証のようなものではないかと思います。
ログインに必要な情報は、
- ユーザー名
- パスワード
です。これは、ユーザーに所属する情報です。
一方、signに必要な情報は、
- 秘密鍵
です。これは、システムに所属する情報です。
このように認証を行うことで、認証の確実性を向上させているのでしょう。
著作権
全てのファイルの冒頭に、
# Copyright (C) 2019 <my name> and contributors
#
# This source code is licensed under the MIT License found in
# the LICENSE file in the root directory of this source tree.
などの表示をしていれば、全てのcontributerに同意を強制できる。というのも、署名の内容に著作権表示が含まれるので、署名がすなわち同意の証拠となる。OSS開発などで、権利の所在をはっきりさせるのに有効な手段だと思う。
Troubleshooting
Git: gpg: skipped "<key id>": No secret key エラー
このエラーが出る原因の一つに、gpgがどこにあるかをgitが知らないということがあります。僕は、Windows10でこの問題が起こっているのを見たことがあります。それに対処するために、署名に使うgpgがどこにあるのかをgitに教えるには、次のコマンドを実行します。
git config --global gpg.program "<path to gpg>"
余談
gpg --list-keys
で出てくる[SC]
や[S]
といった記号の意味は、次の通りです。
文字 | 意味 |
---|---|
E | encryption |
S | signing |
C | certification |
A | authentication |
--list-options parameters
This is a space or comma delimited string that gives options used when listing keys and signatures
...
show-usage
Show usage information for keys and subkeys in the standard key listing. This is a list of letters indicating the allowed usage for
a key (E=encryption, S=signing, C=certification, A=authentication). Defaults to yes.
(man gpg(1))