Git
章節 ▾ 第二版

7.4 Git 工具 - 為您的工作簽章

為您的工作簽章

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

一旦您擁有用於簽署的私密金鑰,您就可以設定 Git,透過設定 user.signingkey 組態設定來使用它來簽署內容。

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

現在,如果您願意,Git 將預設使用您的金鑰來簽署標籤和提交。

簽署標籤

如果您已設定 GPG 私密金鑰,您現在可以使用它來簽署新標籤。您只需使用 -s 而不是 -a 即可

$ 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 及更新版本中,可以使用 --verify-signatures 命令來告知 git mergegit pull 檢查並拒絕合併不帶有可信任 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(+)

您也可以將 -S 選項與 git merge 命令一起使用,以簽署結果的合併提交本身。以下範例同時驗證要合併的分支中的每個提交是否都已簽署,並進一步簽署結果的合併提交。

$ 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