チャプター ▾ 第2版

7.4 Git Tools - 作業への署名

作業への署名

Gitは暗号的に安全ですが、完全ではありません。インターネット上の他者の作業を取り込み、コミットが実際に信頼できるソースからのものであることを確認したい場合、GitはGPGを使用して作業に署名し、検証するいくつかの方法を提供します。

GPGの紹介

まず、署名を行うには、GPGが設定され、個人の鍵がインストールされている必要があります。

$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub   2048R/0A46826A 2014-06-04
uid                  Scott Chacon (Git signing key) <schacon@gmail.com>
sub   2048R/874529A9 2014-06-04

鍵がインストールされていない場合は、`gpg --gen-key`で生成できます。

$ gpg --gen-key

署名するための秘密鍵ができたら、`user.signingkey`設定を設定することで、Gitがそれを使用して署名を行うように設定できます。

$ git config --global user.signingkey 0A46826A!

これで、Gitはデフォルトでタグやコミットに署名するためにあなたの鍵を使用します。

タグへの署名

GPG秘密鍵が設定されていれば、新しいタグに署名するために使用できます。`-a`の代わりに`-s`を使用するだけです。

$ git tag -s v1.5 -m 'my signed 1.5 tag'

You need a passphrase to unlock the secret key for
user: "Ben Straub <ben@straub.cc>"
2048-bit RSA key, ID 800430EB, created 2014-05-04

そのタグで`git show`を実行すると、GPG署名が添付されていることがわかります。

$ git show v1.5
tag v1.5
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:29:41 2014 -0700

my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

タグの検証

署名されたタグを検証するには、`git tag -v `を使用します。このコマンドはGPGを使用して署名を検証します。これを正しく機能させるには、署名者の公開鍵があなたのキーリングにある必要があります。

$ git tag -v v1.4.2.1
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700

GIT 1.4.2.1

Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
gpg:                 aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A

署名者の公開鍵がない場合は、代わりにこのようなものが表示されます。

gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.4.2.1'

コミットへの署名

最近のバージョンのGit(v1.7.9以降)では、個々のコミットに署名することもできます。タグだけでなくコミットに直接署名することに興味がある場合は、`git commit`コマンドに`-S`を追加するだけです。

$ git commit -a -S -m 'Signed commit'

You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04

[master 5c3386c] Signed commit
 4 files changed, 4 insertions(+), 24 deletions(-)
 rewrite Rakefile (100%)
 create mode 100644 lib/git.rb

これらの署名を表示および検証するには、`git log`にも`--show-signature`オプションがあります。

$ git log --show-signature -1
commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
gpg: Signature made Wed Jun  4 19:49:17 2014 PDT using RSA key ID 0A46826A
gpg: Good signature from "Scott Chacon (Git signing key) <schacon@gmail.com>"
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Jun 4 19:49:17 2014 -0700

    Signed commit

さらに、`git log`を設定して、見つかった署名をチェックし、`%G?`形式で出力にリストすることもできます。

$ git log --pretty="format:%h %G? %aN  %s"

5c3386c G Scott Chacon  Signed commit
ca82a6d N Scott Chacon  Change the version number
085bb3b N Scott Chacon  Remove unnecessary test code
a11bef0 N Scott Chacon  Initial commit

ここでは、最新のコミットのみが署名されており有効であり、以前のコミットは署名されていないことがわかります。

Git 1.8.3以降では、`git merge`と`git pull`は、`--verify-signatures`コマンドを使用して、信頼できるGPG署名を持たないコミットをマージする際に検査および拒否するように指示できます。

このオプションをブランチのマージ時に使用し、それが署名されておらず有効でないコミットを含んでいる場合、マージは機能しません。

$ git merge --verify-signatures non-verify
fatal: Commit ab06180 does not have a GPG signature.

マージが有効な署名済みコミットのみを含む場合、マージコマンドはチェックしたすべての署名を表示し、マージを進めます。

$ git merge --verify-signatures signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
Updating 5c3386c..13ad65e
Fast-forward
 README | 2 ++
 1 file changed, 2 insertions(+)

`git merge`コマンドに`-S`オプションを使用して、結果のマージコミット自体に署名することもできます。次の例では、マージされるブランチ内のすべてのコミットが署名されていることを検証し、さらに結果のマージコミットに署名します。

$ git merge --verify-signatures -S  signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>

You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04

Merge made by the 'recursive' strategy.
 README | 2 ++
 1 file changed, 2 insertions(+)

全員が署名する必要がある

タグやコミットへの署名は素晴らしいですが、これを通常のワークフローで使用する場合、チーム全員がその方法を理解していることを確認する必要があります。これは、リポジトリで作業する全員に`git config --local commit.gpgsign true`を実行して、デフォルトですべてのコミットに自動的に署名させることで達成できます。これを行わないと、署名済みのバージョンでコミットを書き換える方法を人々が理解するのを助けるのに多くの時間を費やすことになります。これを標準のワークフローの一部として採用する前に、GPGと署名の利点を理解していることを確認してください。

scroll-to-top