Git
Chapters ▾ 2nd Edition

7.4 Git Tools - Je werk tekenen

Je werk tekenen

Git is cryptografisch veilig, maar beschermt je niet tegen dommigheden. Als je werk overneemt van anderen op het internet en je wilt verifiëren dat commits van een betrouwbare bron komen, heeft Git een aantal manieren om werk te tekenen en verifiëren met GPG.

GPG Introductie

Allereerst, als je iets wilt tekenen zal je eerst GPG moeten hebben geconfigureerd en je persoonlijke sleutel geïnstalleerd.

$ 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

Als je geen sleutel geïnstalleerd hebt, kan je er een genereren met gpg --gen-key.

gpg --gen-key

Als je eenmaal een een privé sleutel hebt om mee te tekenen kan je Git configureren om deze te gebruiken bij het tekenen van spullen door de user.signingkey configuratie sleutel te zetten.

git config --global user.signingkey 0A46826A

Nu zal Git standaard jouw sleutel gebruiken om tags en commits te tekenen als je dat wilt.

Tags tekenen

Als je een GPG privé sleutel aangemaakt hebt, kan je deze gebruiken om nieuwe tags te tekenen. Al wat je hoeft te doen is -s te gebruiken in plaats van -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

Als je nu git show aanroept op die tag, kan je jouw GPG handtekening erbij zien staan:

$ 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

    changed the version number

Tags verifiëren

Om een getekende tag te verifiëren, gebruik je git tag -v [tag-naam]. Dit commando gebruikt GPG om de handtekening te verifiëren. Je hebt de publieke sleutel van de tekenaar nodig in je sleutelbos (keyring) om dit goed te laten werken:

$ 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

Als je de publieke sleutel van de tekenaar niet hebt, krijg je iets als dit:

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'

Commits tekenen

In meer recente versie van Git (v1.7.9 en later), kan je ook individuele commits tekenen. Als je geïnteresseerd bent in het tekenen van ook de commits in plaats van alleen de tags, is alles wat je hoeft te doen een -S toe te voegen aan je git commit commando.

$ 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

Om deze handtekeningen te zien en te verifiëren, is er ook een --show-signature optie bij git log.

$ 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

Bovendien kan je git log configureren om alle handtekeningen die het vind te controleren en deze te laten zien in de uitvoer met het %G? formaat.

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

5c3386c G Scott Chacon  signed commit
ca82a6d N Scott Chacon  changed the version number
085bb3b N Scott Chacon  removed unnecessary test code
a11bef0 N Scott Chacon  first commit

Hier kunnen we zien dat alleen de laatste commit is getekend en geldig en de eerdere commits niet.

In Git 1.8.3 en later, kunnen "git merge" en "git pull" verteld worden om te controleren tijdens het mergen van een commit en deze af te wijzen als die geen geverfieerde GPG handtekening heeft met het --verify-signature commando.

Als je deze optie gebruikt tijdens het mergen van een branch en die commits bevat die niet getekend en geldig zijn zal de merge niet slagen.

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

Als de merge alleen maar geldig getekende commits bevat, zal het merge commando je alle handtekenignen laten zien die het heeft gecontroleerd en daarna doorgaan met de merge.

$ 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(+)

Je kunt ook de -S optie gebruiken met het git merge commando om de merge die het resultaat hiervan is te tekenen. Het volgende voorbeeld zal zowel elke commit in de te mergen branch verifiëren als de resulterende merge commit tekenen.

$ 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(+)

Iedereen moet tekenen

Tags en commits tekenen is geweldig, maar als je besluit dit te gaan gebruiken in je reguliere workflow, moet je er zeker van zijn dat iedereen in je team begrijpt hoe dit te doen. Als je dat niet doet, ga je erg veel tijd kwijt zijn met het uitleggen aan mensen hoe ze hun commits moeten vervangen met getekende versies. Zorg ervoor dat je GPG begrijpt en het voordeel van getekende dingen voordat je dit gaat gebruiken als onderdeel van je reguliere workflow.