GitHubのコミットにverifiedをつける

# 初めに
タイトルの通りです。
Windows環境上でコミット時、タグやコミット時にサインすることで本人が行った動作と証明します。

## 想定している人
- ラクに✔マークをつけたい人
- ほかのページだと断片化しすぎててわかんなかった人

## Verifiedとは
GitHubのcommitなりtagなりについてるこんな感じのやつです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147334/ca3495c8-4a1f-735a-c0a6-7985526b3863.png)

このマークがついていることで鍵を適切に管理した場合その本人しか署名できないため、
本人がその操作を行ったことを確認できます。
また、GitHubでも署名を行ったコミットが上がってきたときに、本当に自分のかをチェックする機構があり、
それに通ればVerifiedマークがつく、といった流れです。
Gitの公式サイトを見る限りには[「ぜひやってくれ」的な体制](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)らしいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147334/41c26916-9d65-655d-9680-6d3bc331f183.png)

# やり方
## 前提環境
- [Git](https://git-scm.com/downloads) for Windows 2020/08/23時点でのStable Buildは2.28.0だそうです
- [GnuPG](https://www.gpg4win.org/thanks-for-download.html) [署名確認](https://www.gpg4win.org/package-integrity.html): Git組み込みのものもあります。今回はこちらで。
- GitHubのアカウント: それはそう

## 使用する個人名とメールアドレスの確認
GitHubでは、メールアドレスを晒すのは…という人向けに、GitHub側でメールアドレスを隠してくれる機構([Email](https://github.com/settings/emails)の`Keep my email addresses private`)があります。
もしその機構を利用している場合はのであれば、そのメールを使用してください。利用していないのであればGitHubの`Primary email address`を利用して下さい。
EDIT: この機構を使用する場合、他サービス(GitLab等)に移した際に認証が切れてしまうことを考慮してください。

## 鍵の作成
対話型で作成可能な方法もあります。今回は省略します。  

- `gpg --quick-gen-key "名前 <メール>" future-default - 0`で、最も短い形で鍵の作成が可能です。パスフレーズはダイアログとして出てくるので、そちらにコミットする際のパスフレーズを指定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147334/a366c1ac-ca02-081a-da95-c8bd4950eb45.png)  
これで作成完了すると下の様に出力されたはずです。
この例でいう`EB13FBB100DB367482FE6826A5F9ED5C4F044D21`をこの後使用します。　　

```
C:\Users\kazu0617>gpg --quick-gen-key "kazu0617 <kazu0617@**********.com>" future-default - 0
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
たくさんのランダム・バイトの生成が必要です。キーボードを打つ、マウスを動か
す、ディスクにアクセスするなどの他の操作を素数生成の間に行うことで、乱数生
成器に十分なエントロピーを供給する機会を与えることができます。
gpg: 鍵A5F9ED5C4F044D21を究極的に信用するよう記録しました
gpg: 失効証明書を 'C:/Users/kazu0617/AppData/Roaming/gnupg/openpgp-revocs.d\EB13FBB100DB367482FE6826A5F9ED5C4F044D21.rev' に保管しました。
公開鍵と秘密鍵を作成し、署名しました。

pub   ed25519 2020-08-22 [SC]
      EB13FBB100DB367482FE6826A5F9ED5C4F044D21
uid                      kazu0617 <kazu0617@**********.com>
sub   cv25519 2020-08-22 [E]
```
- GitHubに使用する鍵を伝えるため、公開鍵を出力します。    

```
C:\Users\kazu0617>gpg --armor --export EB13FBB100DB367482FE6826A5F9ED5C4F044D21
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEX0Fr0BYJKwYBBAHaRw8BAQdAKaJSb/8su93/TeaOqUm4IU71wAQp2pSuvap/
OqmBbTq0ImthenUwNjE3IDxrYXp1MDYxN0Bwcm90b25tYWlsLmNvbT6IkAQTFggA
OBYhBOsT+7EA2zZ0gv5oJqX57VxPBE0hBQJfQWvQAhsDBQsJCAcCBhUKCQgLAgQW
AgMBAh4BAheAAAoJEKX57VxPBE0hbJkA/2BBxW/YlkHvn13GhEpIZTRXL3dw3oTP
zKOt9xgWuiwwAP9adwB+lHPEfGJXpETl09P2Nuwn4e6oRMZOL+vZOoY/C7g4BF9B
a9ASCisGAQQBl1UBBQEBB0AoHDxYTEJAW0lViP6tYkUjdIJI/j5Tl8qdAvrD3aRE
dwMBCAeIeAQYFggAIBYhBOsT+7EA2zZ0gv5oJqX57VxPBE0hBQJfQWvQAhsMAAoJ
EKX57VxPBE0hm/IA/3RO+iNvvXrleq1l8qhg/QnV5DnqjdXTrN/CMRl9OyDaAQCy
UDcITSqFmZSxb5ivd9+BQcrZovyqpx67t7601mDYCA==
=gT34
-----END PGP PUBLIC KEY BLOCK-----
```
ここまで来たらこの後これら公開鍵情報を使用するため、ここの内容を全てコピーしてください。

## GitHub上での設定
1. GitHubから、[SSH and GPG Keys](https://github.com/settings/keys)にアクセス。ここでSSHやPGPの鍵を確認します。
2. `New GPG Key`をクリック。出てきた枠に先ほどコピーした内容を貼り付けて、Add GPG Keysで登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147334/3789e184-333f-a2d2-067a-592353b4b1cc.png)


3. 画面が遷移し、鍵が追加されたことが確認できるはずです。ここのDeleteをクリックすれば鍵を削除可能です（今回の鍵は無期限指定のため、何か問題がない限りはずっと使用し続けることができます）。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147334/0a7decec-e994-77e8-413f-4328fd652035.png)

EDIT:Unverifiedになってますがメールに送信されたURLをクリックするとVerifiedになります。
GitHubから払い出されたnoreplyメール以外で応答しないメールだとメールに到達できないのでVerifiedにはなりません。


P.S. CUI上で行う方法もあるみたいです。何度もやってて面倒だという方はどうぞ。
https://qiita.com/yusuke_konishi/items/6fa51372a895c831ab2b

## git側の設定
gitに登録する際にkeyidを指定しなければいけないため、それを`gpg --list-secret-keys --keyid-format LONG`から確認します。  
今回の例であればssbである`2651E81CE5ACB365`が今回使用する秘密鍵となります  
(secである`A5F9ED5C4F044D21`も利用できますし、そういったポストもありますが、現実でいうマスターキーで常に施錠する形なので、基本的には署名には使用せず鍵の更新とかだけに使用するのが望ましいと言われています)。

```
C:\Users\kazu0617>gpg --list-secret-keys --keyid-format LONG
sec   ed25519/A5F9ED5C4F044D21 2020-08-22 [SC]
      EB13FBB100DB367482FE6826A5F9ED5C4F044D21
uid                 [  究極  ] kazu0617 <kazu0617@**********.com>
ssb   cv25519/2651E81CE5ACB365 2020-08-22 [E]
```
次の通りに実際に情報をgit側に反映させます。  
`gpg.program`や`commit.gpgsign`はもしかするとインストール時に入っているかもしれません。その場合は改めて追加する必要はありません。`user.name`や`user.email`を既に指定している場合は`user.signingkey`だけで十分です。  
(よくわからない場合は`git config --global --edit`や`git config --edit`から現在情報を確認可能)

```
git config --global add gpg.program "c:/Program Files (x86)/GnuPG/bin/gpg.exe"
git config --global add commit.gpgsign true
git config --global add user.name kazu0617
git config --global add user.email kazu0617@**********.com
git config --global add user.signingkey 2651E81CE5ACB365
```
一応それぞれについて補足
- gpg.program ... gpgのプログラムを指定してます
- commit.gpgsign ... コミットに対しgpgを標準でサインする
- user.name ... 自分の名前
- user.email ... 今回使用したメールアドレス(GitHubで使えるもの)
- user.signingkey ... KeyID.上の例だと`2651E81CE5ACB365`

他サービスと共存する場合は、`user.email`と`user.signingkey`はローカルに保存することでリポジトリごとにキーを変更できるため、GitLabとの共存も可能のためお勧めです。

# コミットの仕方  
先ほど`commit.gpgsign`を適用したため、通常と同じやり方でコミットしてもらえればコミットされます。変更点といえばコミットする際に鍵を使用するため、その際のパスフレーズが求められるぐらいです。

<details><summary>gpgsignを適用しない場合</summary>
<a href="https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work">公式サイトの記述</a>から、おおよそ次のような感じです。<ul><li> コミットをする際には-Sをつける</li><li>タグをつける際には-sを使う</li></ul>そのため、例えばコミットの場合であれば`git commit -S ...`といった形で引数を付与してあげることで任意のコミットに引数を付与することができます。
</details>

# 参考
- [What do 'ssb' and 'sec' mean in gpg's output?](https://superuser.com/questions/1371088/what-do-ssb-and-sec-mean-in-gpgs-output)
- [Telling Git about your signing key](https://docs.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key)
- [GnuPG チートシート（鍵作成から失効まで）](https://text.baldanders.info/openpgp/gnupg-cheat-sheet/)
- [そろそろ GnuPG でも ECC を標準で使うのがいいんじゃないかな](https://text.baldanders.info/openpgp/using-ecc-with-gnupg/)


# 最後に
失効させる場合や鍵の更新などについては機会があれば投稿します。また、何か問題点や質問があればコメントやTwitter等に直接どうぞ。