GitのコミットにSSH鍵で署名してGitHub上でVerifiedマークをつけよう！

# 概要
- コミットは簡単になりすましができてしまう
- なりすまし防止のためコミットに署名することができる
- おすすめはSSH鍵を用いた署名
    - GitHubのSSH認証に用いている鍵を使い回せるため
- コミットを署名&GitHubで検証できるようにして、**Verified** マークをつけよう
![Untitled-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/177ddabc-e8aa-07a2-c9f5-8f5f3474ca54.png)

# 背景
## コミットは偽装できる
https://qiita.com/s6n/items/bb869f740a53a3bf169e

こちらの記事で紹介されているように、Gitのコミットは **ユーザー名とメールアドレス** さえわかれば、簡単に他人がコミットを行ったかのように偽装できてしまいます。
これでは悪意のある人が、信頼されているユーザーになりすまして悪意のあるコードをコミットすることができてしまいます。

## コミットに署名してなりすましを防ぐ

なりすましを防ぐため、Gitにはコミットに署名して検証する仕組みがあります。

https://docs.github.com/ja/authentication/managing-commit-signature-verification/about-commit-signature-verification

署名したコミットをGitHubにプッシュするとGitHub側で検証され、正しく検証された場合は以下のように **Verified** マークがつきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/aa7fb08e-43d3-928c-9468-55732d663456.png)

GitHubのブランチ保護ルールでは検証済みのコミットのみをマージできるルールを設定することもできるので、より強固になりすましを防止できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/a726e6ac-a257-7ca5-6aba-cc74b838c23a.png)


# SSH鍵を使ってコミットに署名する
ここから本題です。

コミットに署名するには以下の方法があります。

- GPG
- SSH
- S/MIME

この中でもおすすめは **SSH** です。
理由として、GitHubへの接続にSSH認証を使用している場合、そのSSH鍵をコミット署名に再利用できるためです。
本記事では **SSH** を使って署名する方法を紹介します。

> 注: SSH 署名の検証は、Git 2.34 以降で利用できます。

以下の順に行っていきます。

1. 新しい SSH キーを生成する
1. GitHub アカウントに SSH 署名キーを追加する
1. Git へ署名キーを伝える
1. コミットに署名する

## 新しい SSH キーを生成する

まずはSSHキーを作成します。
すでにSSH認証を使用している場合はこの手順をスキップできます。

```
ssh-keygen -t ed25519 -C "your_email@example.com"
```
以下が出てきた場合はそのまま Enter キーを押します。
```
Generating public/private ed25519 key pair.
Enter file in which to save the key (/root/.ssh/id_ed25519):
```

パスフレーズはここではなしで進めます。
以下が出てきたらそのまま Enter キーを押します。
```
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```
> よりセキュアに利用するにはパスフレーズを設定することをおすすめします。
> 通常パスフレーズを設定すると秘密鍵を使用するたびにパスフレーズの入力が求められますが、`ssh-agent` を利用することで毎回の入力を回避することができます。
> 詳しくは以下の記事を参照してください。

https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent

これでSSH鍵を作成できました。
`Enter file in which to save the key`で指定したディレクトリに秘密鍵と公開鍵の2つのファイルが作成されます。

```
root@1f9727978628:/# ls ~/.ssh
id_ed25519  id_ed25519.pub
```

## GitHub アカウントに SSH 署名キーを追加する

続いてコミット署名検証用の公開鍵をGitHubに登録します。

1. 公開鍵をコピーする
    ```
    cat ~/.ssh id_ed25519.pub
    ```
1. GitHubの設定を開く
1. **SSH and GPG keys** を開く
1. **New SSH key** をクリックする
1. **Title** には任意の名前をつける
1. **Key type** は **Signing Key** を選択する
1. **Key** に先ほどコピーした公開鍵の中身を貼り付ける
    > このとき、改行などが含まれないように注意する
1. **Add SSH key**をクリックする

これでGitHub側の設定は完了です。

## Git へ署名キーを伝える

コミット時に先ほど作成したSSH鍵で署名するようにGitの設定をします。

1. コミットの署名にSSHを使うよう設定
    ```
    git config --global gpg.format ssh
    ```
1. GitにSSH署名キーを設定
    ```
    git config --global user.signingkey ~/.ssh/id_ed25519.pub
    ```

`~/.gitconfig`を直接編集する場合は以下のようにします。
```:~/.gitconfig
[gpg]
        format = ssh
[user]
        signingkey = /root/.ssh/id_ed25519.pub
        name = Your Name
        email = your_email@example.com
```

## コミットに署名する

コミット時に署名するには `-S` フラグをつけます。
```
git commit -S -m "update README.md"
```

GitHubにプッシュして、**Verified** マークを確認します。

リポジトリのページを開き、**Commits** をクリックすると確認できます。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/10dc1357-fae7-b260-35dd-e782c5de55fa.png)
![Untitled-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/177ddabc-e8aa-07a2-c9f5-8f5f3474ca54.png)

毎回 `-S` オプションをつけずとも、デフォルトでコミット署名を設定することもできます。

下記コマンドを実行するか、`~/.gitconfig`に以下を追記します。
```
git config --global commit.gpgsign true
```
```:~/.gitconfig
[commit]
    gpgsign = true
```

# 参考記事

https://docs.github.com/ja/authentication/managing-commit-signature-verification/about-commit-signature-verification

https://qiita.com/s6n/items/bb869f740a53a3bf169e