MacでGPGの鍵を生成してGitHubでコミットの署名を表示する

# MacでGPGの鍵を生成してGitHubに登録する

<img width="299" alt="signature.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13809/bc7034ce-7c53-e258-a015-c6dc25c532d2.png">

GitHubではコミットの署名が表示できる。
GPG鍵を生成して署名の表示までを行う流れをメモする。

## 環境

gpgのバージョン。

```
$ gpg --version
gpg (GnuPG) 2.2.19
...
```

Macのバージョン。

```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.1
BuildVersion:	19B88
```

## 鍵の生成

鍵を生成する。

```
$ LANG=C gpg --full-gen-key
```

鍵の種類は`1`を入力する。(RSA and RSAを選択する)

```
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
```

鍵の長さは最大の`4096`を入力する。

```
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
```

有効期限はデフォルトの`0`のままで良い。

```
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)
```

上記までで不備がなければ`y`を入力する。

```
Key does not expire at all
Is this correct? (y/N) y
```

名前とメールアドレスを入力する。このときメールアドレスはGitHubに登録したものを入力する。
コメントは不要。

```
GnuPG needs to construct a user ID to identify your key.

Real name: YOUR_NAME
Email address: YOUR_EMAIL_ADDRESS
Comment:
You selected this USER-ID:
    "YOUR_NAME <YOUR_EMAIL_ADDRESS>"
```

上記までで不備がなければ`O`を入力する。

```
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
```

パスフレーズの入力が求められるので入力する。
入力後以下のような文言が表示されるのでマウスポインタを適当に動かす。
何もしないとタイムアウトするので注意。

```
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.
```

終わると以下のように鍵生成に成功する。

```
gpg: /Users/YOUR_NAME/.gnupg/trustdb.gpg: trustdb created
...
```

## GitHubへの登録

GPGのリストを表示し、GPGのkey IDを確認する。

```
$ gpg --list-secret-keys --keyid-format LONG
---------------------------------
sec   rsa4096/123456789ABCDEFG 2019-10-10 [SC]
      ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD
uid                 [  究極  ] YOUR_NAME <YOUR_EMAIL_ADDRESS>
ssb   rsa4096/ABCDEFGHIJKL1234 2019-10-10 [E]
```

ASCII armor formatのKey IDを確認する。

```
$ gpg --armor --export 123456789ABCDEFG
-----BEGIN PGP PUBLIC KEY BLOCK-----
....
-----END PGP PUBLIC KEY BLOCK-----
```

`-----BEGIN PGP PUBLIC KEY BLOCK-----`から`-----END PGP PUBLIC KEY BLOCK-----`までをコピーして、GPG鍵を登録する。

- https://github.com/settings/gpg/new

## signingkeyの設定


gitの設定にsigningkeyを追加する。

```
$ git config --global user.signingkey 123456789ABCDEFG
```

## 署名をつけてコミット

`-S` フラグを付けることで署名ができる。

```
$ git commit -m'Test' --allow-empty -S
```

Pushする。

```
$ git push
```

pushしたりリポジトリをGitHubで確認すると、冒頭に紹介したようなコミットの署名が表示される。

## ハマったところ

コミット時にエラーが発生した。

```
$ git commit -m'Test' --allow-empty -S
error: gpg failed to sign the data
fatal: failed to write commit object
```

`No pinentry`がないらしい。

```
$ echo "test" | gpg --clearsign
...
gpg: [stdin]: clear-sign failed: No pinentry
```

pinentry-macをインストールすることで解決した。

```
$ brew install pinentry-mac
...
==> Downloading https://homebrew.bintray.com/bottles/pinentry-mac-0.9.4.catalina.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/93/936dba5c3bdd8279e5380012645a349a6ef8c69d1cc9066f28
######################################################################## 100.0%
==> Pouring pinentry-mac-0.9.4.catalina.bottle.tar.gz
==> Caveats
You can now set this as your pinentry program like

~/.gnupg/gpg-agent.conf
    pinentry-program /usr/local/bin/pinentry-mac
==> Summary
🍺  /usr/local/Cellar/pinentry-mac/0.9.4: 12 files, 424.9KB
```

## パスフレーズの入力をプロンプトではなくパスフレーズの入力ウィンドウを表示させる ※ 2020/2/16追記

gpgの設定を変更し、pinentry-macを利用するように変更。
```
$ echo "pinentry-program /usr/local/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf
```

agentをkillする。
```
$ gpgconf --kill gpg-agent
```

パスフレーズの入力するウィンドウを表示させる。
```
$ echo "test" | gpg --clearsign
```

## 参考

- [Managing commit signature verification - GitHub Help](https://help.github.com/en/github/authenticating-to-github/managing-commit-signature-verification)