🔑

GitHubへGPG署名つきでコミットする手順

commits15 min read

サマリー

GitHubGnuPG による署名つきのコミットを行うと Verified と表示されるようにします。

前提

  • Homebrew はインストール済み (macOS)
  • Git Bash もしくは何らかの Unix シェルを準備済み (Windows)
  • なんらかの GitHub レポジトリを作成済み

手順

1. git のインストール (macOS)

Git for Windows (Git Bash) には git コマンドが同梱されています。
WSL2 の場合には、その Linux ディストリビューションのパッケージを利用してください。

macOS に標準搭載されている git コマンドは少しバージョンが古いので、brew install コマンドで最新版をインストールします。

zsh
% brew install git
% which git

# Apple Silicon の場合
/opt/homebrew/bin/git

# Intel Mac の場合
/usr/local/bin/git

% git --version
git version 2.33.0

2. git の設定(その1)

まずは GitHub のアカウント名とメールアドレスを設定します。

zsh
% git config --global user.name "あなたの GitHub アカウント名"
% git config --global user.email "あなたのメールアドレス"

現在の設定を確認するには --list オプションを使います。

zsh
% git config --global --list
user.name=taro_zenn
user.email=zenn@examle.com

ここでのアカウント名やメールアドレスの例は実在の人物や組織とは関係ありません。

また、ホームディレクトリへ .gitconfig というファイルが作られていることが確認できます。

zsh
% cat ~/.gitconfig
[user]
	name = taro_zenn
	email = zenn@example.com

3. gnupg (以下、gpg)のインストール (macOS)

gnupg コマンドも Git for Windows (Git Bash) に同梱されています。

環境にもよりますが、結構時間がかかります。

zsh
% brew install gnupg

% which gpg
/opt/homebrew/bin/gpg

% gpg --version
gpg (GnuPG) 2.3.1
libgcrypt 1.9.3
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

4. pinentry-mac のインストール (macOS)

Git for Windows (Git Bash) には pinentry も同梱されています。

パスフレーズの入力ダイアログを提供する pinentry-mac というプログラムも必要となります。

zsh
% brew install pinentry-mac

~ 中略 ~
==> Caveats
You can now set this as your pinentry program like

~/.gnupg/gpg-agent.conf
    pinentry-program /opt/homebrew/bin/pinentry-mac

Homebrew の指示に従って pinentry-program を設定します。

zsh
# `which pinenty-mac` で得られたパスを指定
% echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf

5. gpg 鍵の作成

すでに gpg 鍵を持っていて、それを Mac or PC へインポートする場合は第 8 節まで飛ばしてください。

署名につかう gpg 鍵を作成します。
gpg --gen-key コマンドを実行してください。

zsh
% gpg --gen-key
gpg (GnuPG) 2.3.1; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

注意: 全機能の鍵生成には "gpg --full-generate-key" を使います。

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

本名: Taro Zenn                      # <-- 名前を入力
電子メール・アドレス: zenn@example.com  # <-- GitHub に登録したアドレスを入力
次のユーザIDを選択しました:
    "Taro Zenn <zenn@example.com>"

名前(N)、電子メール(E)の変更、またはOK(O)か終了(Q)? O  # <-- O を入力

ここでエラーが発生する場合は、gpg-agent がすでに起動してしまっていることが原因だと思われます。
gpgconf コマンドでこれを終了させてからもう一度試してみてください。

zsh
% gpgconf --kill gpg-agent

pinentry のダイアログが表示されたら、パスワードを入力して OK をクリックしてください。

以下のようなメッセージが表示されたら、鍵作成の完了です。

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

pub   ed25519 2021-08-19 [SC] [有効期限: 2023-08-19]
      382DCB6AE30805248F3D05CFD5335BA3024DD307
uid                      Taro Zenn <zenn@example.com>
sub   cv25519 2021-08-19 [E] [有効期限: 2023-08-19]

gpg -k コマンドで現在の公開鍵一覧を確認しましょう(-K オプションを使うと秘密鍵一覧)。

zsh
% gpg -k

gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   2  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 2u
gpg: 次回の信用データベース検査は、2022-11-28です
/Users/zenn/.gnupg/pubring.kbx
-------------------------------
pub   ed25519 2021-08-18 [SC] [有効期限: 2023-08-18]
      73E939B96DA34BCB70CBD4923D5480AA3DF9D84F
uid           [  究極  ] Taro Zenn <zenn@example.com>
sub   cv25519 2021-08-18 [E] [有効期限: 2023-08-18]

6. gpg 公開鍵のエクスポート

この鍵を GitHub に登録するため、ファイルへ公開鍵をエクスポートします。

zsh
% gpg -a --export "あなたのメールアドレス" > pubkey.gpg

-a オプションを用いることで平文(プレーンテキスト)で出力されます。

zsh
% cat pubkey.gpg
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEYR2cyRYJKwYBBAHaRw8BAQdAfczM5JrK6r8U+x+rQoiEbRYIeEoXbtGGU42h
N1OMaBy0HFRhcm8gWmVubiA8emVubkBleGFtcGxlLmNvbT6ImgQTFgoAQhYhBHPp
Oblto0vLcMvUkj1UgKo9+dhPBQJhHZzJAhsDBQkDwmcABQsJCAcCAyICAQYVCgkI
CwIEFgIDAQIeBwIXgAAKCRA9VICqPfnYT5jCAQCI5zeN+wycTrNmf02+Cr6hzEDk
kDbgiRGr3+NOqdADUQD9H933zY3qNcx2qvgLENaA0ieA0cHqv+8pqnzutJH0DQq4
OARhHZzJEgorBgEEAZdVAQUBAQdANNhjv3+GT+/wSaQl8icZQZvaB/gelzRSQydj
ueteJC8DAQgHiH4EGBYKACYWIQRz6Tm5baNLy3DL1JI9VICqPfnYTwUCYR2cyQIb
DAUJA8JnAAAKCRA9VICqPfnYTw9VAQCRJT53OHlsg3wvl9gTLbBjQ8zogLF+Kyml
DUS96PxdPgD/bvdup4CpUqwMovTygdrYOgYIa9G+4eCaaVptPnldcwU=
=Qold
-----END PGP PUBLIC KEY BLOCK----

7. gpg 秘密鍵のエクスポート

秘密鍵をファイルへエクスポートし、このファイルは大切に保管してください。

zsh
% gpg -a --export-secret-key "あなたのメールアドレス" > seckey.gpg

8. 既存の gpg 鍵をインポートする場合

すでに gpg 鍵を作成済みの場合は、その鍵の秘密鍵をインポートします。

zsh
% gpg --import seckey.gpg

pinentry のダイアログが表示されたらパスフレーズを入力して OK をクリックします。

以下のように表示されればインポートは成功です。

zsh
gpg: 鍵D594B27E9EE46CB4: 公開鍵"Taro Zenn <zenn@example.com>"をインポートしました
gpg: 鍵D594B27E9EE46CB4: 秘密鍵をインポートしました
gpg:           処理数の合計: 1
gpg:             インポート: 1
gpg:       秘密鍵の読み込み: 1
gpg:     秘密鍵のインポート: 1

秘密鍵をインポートすると一緒に公開鍵もインポートされます。

gpg -k コマンドで確認しましょう。

zsh
% gpg -k
gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   1  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 1u
gpg: 次回の信用データベース検査は、2022-11-28です
/Users/zenn/.gnupg/pubring.kbx
-------------------------------
pub   ed25519 2021-08-19 [SC] [有効期限: 2023-08-19]
      0536B7DDDAD6517D838D9761D594B27E9EE46CB4
uid           [  不明  ] Taro Zenn <zenn@example.com>
sub   cv25519 2021-08-19 [E] [有効期限: 2023-08-19]

鍵の信頼度が [ 不明 ] となってしまっているので、これを gpg --edit-key コマンドで修正します。

zsh
% gpg --edit-key "あなたのメールアドレス"
gpg (GnuPG) 2.3.1; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

秘密鍵が利用できます。

sec  ed25519/D594B27E9EE46CB4
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: SC
     信用: 不明の     有効性: 不明の
ssb  cv25519/9A295851C499127E
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: E
[  不明  ] (1). Taro Zenn <zenn@example.com>

gpg> trust  # <-- `trust` と入力

ec  ed25519/D594B27E9EE46CB4
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: SC
     信用: 不明の     有効性: 不明の
ssb  cv25519/9A295851C499127E
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: E
[  不明  ] (1). Taro Zenn <zenn@example.com>

他のユーザの鍵を正しく検証するために、このユーザの信用度を決めてください
(パスポートを見せてもらったり、他から得たフィンガープリントを検査したり、などなど)

  1 = 知らない、または何とも言えない
  2 = 信用し ない
  3 = まぁまぁ信用する
  4 = 充分に信用する
  5 = 究極的に信用する
  m = メーン・メニューに戻る

あなたの決定は?   # <-- 1~5 の数字を入力して Enter

通常は自分が作成した鍵であることが明白でしょうから、大抵の場合は 5 を入力することになると思います。

zsh
あなたの決定は? 5
本当にこの鍵を究極的に信用しますか? (y/N) y  # <-- `y` を入力(大文字の選択肢のほうがデフォルト)

sec  ed25519/D594B27E9EE46CB4
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: SC
     信用: 究極        有効性: 不明の
ssb  cv25519/9A295851C499127E
     作成: 2021-08-19  有効期限: 2023-08-19  利用法: E
[  不明  ] (1). Taro Zenn <zenn@example.com>
プログラムを再起動するまで、表示された鍵の有効性は正しくないかもしれない、
ということを念頭においてください。

gpg> quit  # <-- `quit` と入力して編集画面を終了

再度、gpg -k コマンドで確認しましょう。

zsh
% gpg -k

gpg: 信用データベースの検査
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深さ: 0  有効性:   2  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 2u
gpg: 次回の信用データベース検査は、2022-11-28です
/Users/zenn/.gnupg/pubring.kbx
-------------------------------
pub   ed25519 2021-08-19 [SC] [有効期限: 2023-08-19]
      0536B7DDDAD6517D838D9761D594B27E9EE46CB4
uid           [  究極  ] Taro Zenn <zenn@example.com>
sub   cv25519 2021-08-19 [E] [有効期限: 2023-08-19]

9. GitHub へ gpg 公開鍵を登録する

GitHub の Settings>SSH and GPG keysページを開き、New GPG key ボタンをクリックします。

エクスポートされた公開鍵の内容をここへコピー&ペーストし、Add GPG key ボタンをクリックします。

zsh
# macOS
% cat pubkey.gpg | pbcopy

# Windows
$ cat pubkey.gpg > /dev/clipboard

# 公開鍵の内容がクリップボードへ送られたので、
# これをブラウザの画面へ Cmd+V or Ctrl+V でペーストする

10. SSH 鍵の作成

つづいて GitHub へ登録する SSH 鍵を作成します。

https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
zsh
% ssh-keygen -t ed25519 -C "あなたのメールアドレス"

Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/zenn/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/zenn/.ssh/id_ed25519.
Your public key has been saved in /Users/zenn/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:M6jeZYosBNpMU93jEpr2IJUJY91wlYpBFvhoxucsV6Q zenn@example.com
The key's randomart image is:
+--[ED25519 256]--+
|  +==B.o..       |
| ..oB.= +        |
| . = B + .       |
|. O E +..        |
|.B B +..S        |
|. = +..  o       |
| . o.   o        |
|  .o o +         |
|   .+ o          |
+----[SHA256]-----+

基本的に Enter 連打でも構いませんが、気になる場合はパスワードや出力ファイル名などを適宜指定してください。

11. GitHub へ SSH 公開鍵を登録する

ふたたび Settings>SSH and GPG keysページを開き、New SSH key ボタンをクリックします。

Title へ適当なタイトルを付け、 Key~/.ssh/id_ed25519.pub の内容をコピー&ペーストします。

zsh
# macOS
% cat ~/.ssh/id_ed25519.pub | pbcopy

# Windows
$ cat ~/.ssh/id_ed25519.pub > /dev/clipboard

コピべするのは *.pub が付いているほうのファイルです。拡張子なしのファイルのほうは秘密鍵なので大切に扱ってください。

12. SSH 接続の設定

ssh github のコマンド実行のみで GitHub へ SSH 接続できるように ~/.ssh/config ファイルを作成します。

.ssh/config
Host github
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519

13. GitHub へ SSH 接続してみる

では、さっそく SSH 接続してみましょう。

zsh
% ssh github

~ 中略 ~
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
                                                         # <-- yes と入力

PTY allocation request failed on channel 0
Hi zenn! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

「認証できたけど、GitHub ではシェルアクセスを提供していないので切断するよ」という旨のメッセージが表示されれば成功です。

14. git の設定(その2)

コミット時に gpg による署名を必要とするように設定を追加します。

zsh
# 公開鍵一覧の確認
% gpg -k
/Users/zenn/.gnupg/pubring.kbx
-------------------------------
pub   ed25519 2021-08-19 [SC] [有効期限: 2023-08-19]
      382DCB6AE30805248F3D05CFD5335BA3024DD307
uid           [  究極  ] Taro Zenn <zenn@example.com>
sub   cv25519 2021-08-19 [E] [有効期限: 2023-08-19]

# gpg コマンドのパスを登録
% git config --global gpg.program `which gpg`

# 上の gpg -k コマンドで表示された鍵の ID を指定
% git config --global user.signingkey "382DCB6AE30805248F3D05CFD5335BA3024DD307"

# コミット時に gpg による署名をおこなう
% git config --global commit.gpgsign true

# 設定の確認
% git config --global --list

user.name=taro_zenn
user.email=zenn@example.com
user.signingkey=382DCB6AE30805248F3D05CFD5335BA3024DD307
gpg.program=/opt/homebrew/bin/gpg
commit.gpgsign=true

15. 署名つきでコミットしてみる

適当なディレクトリを作成し、git レポジトリとして初期化します。

zsh
% mkdir gpg-test
% cd gpg-test
% git init

空のファイルを作成し、これをコミットしてみましょう。

zsh
% touch empty.txt
% git add -A
% git commit -m "first commit"

macOS

pinenty のダイアログが表示されれば、これで gpg のための設定は完了です。
Save in Keychain のチェックはお好みでどうぞ。

Windows

CredentialHelperSelector が表示されたら、そのまま Select をクリックします。
Always use this from now on のチェックはお好みでどうぞ。

pinenty のダイアログが表示されれば、これで gpg のための設定は完了です。

16. GitHub レポジトリの設定

すでに存在する GitHub レポジトリで、そのレポジトリの特定ブランチへの PUSH 時には gpg 署名が必須となるように設定します。

対象としたい GitHub レポジトリのページから、Settings>Branches へとすすみ、Add rule ボタンをクリックします。

Branch name pattern へ対象とするブランチ名を入力し、

Require signed commits をチェックして Create ボタンをクリックします。

最後に Save changes ボタンをクリックして完了です。

17. GitHub へプッシュしてみる

では、このブランチへプッシュしてみましょう。

zsh
% git push

Warning: Permanently added the RSA host key for IP address '52.192.72.89' to the list of known hosts.
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.21 KiB | 1.21 MiB/s, done.
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.

~ 以下略 ~

このコミットから Verified となりました。

GitHubで編集を提案

Discussion

ログインするとコメントできます