Git
Chapters ▾ 2nd Edition

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 να το χρησιμοποιεί για να υπογράφουμε θέτοντας τη ρύθμιση config_server.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

    changed the version number

Επαλήθευση ετικετών

Για να επαληθεύσουμε μια υπογεγραμμένη ετικέτα, χρησιμοποιούμε την εντολή git -v [tag-name]. Αυτή η εντολή χρησιμοποιεί το 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 και παραπάνω), μπορούμε πλέον να υπογράφουμε και μεμονωμένες υποβολές. Αν ενδιαφερόμαστε να υπογράψουμε υποβολές απευθείας αντί μόνο τις ετικέτες, το μόνο που χρειάζεται να κάνουμε είναι να προσθέσουμε ένα -S στην εντολή μας ‘git commit’.

$ 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

Για να δούμε και να επαληθεύσουμε αυτές τις υπογραφές, υπάρχει επίσης η επιλογή --show-signature στην 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

Επιπλέον, μπορούμε να διαμορφώσουμε την git log να ελέγχει τυχόν υπογραφές που βρίσκει και να τις παραθέτει στην έξοδο της με τη μορφή %G?.

$ 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

Εδώ μπορούμε να δούμε ότι μόνο η πιο πρόσφατη υποβολή είναι υπογεγραμμένη και έγκυρη, ενώ οι προηγούμενες υποβολές δεν είναι.

Από το Git 1.8.3 και μετά, είναι δυνατό το πούμε στις git merge και git pull να επιθεωρούν και να απορρίπτουν όταν συγχωνεύσουν μια υποβολή που δεν φέρει αξιόπιστη υπογραφή GPG με την εντολή --verify-signatures.

Εάν χρησιμοποιούμε αυτήν την επιλογή όταν συγχωνεύουμε έναν κλάδο και περιέχει υποβολές που δεν είναι υπογεγραμμένες και έγκυρες, η συγχώνευση δεν γίνεται.

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

Όλοι πρέπει να υπογράψουν

Η υπογραφή ετικετών και υποβολών είναι σπουδαία, αλλά αν αποφασίσουμε να τη χρησιμοποιούμε στη φυσιολογική ροή εργασίας μας, θα πρέπει να βεβαιωθούμε ότι όλοι στην ομάδα μας κατανοούν πώς να το κάνουν. Εάν δεν το κάνουμε, θα καταλήξουμε να αφιερώνουμε πολύ χρόνο βοηθώντας τους άλλους να καταλάβουν πώς να ξαναγράψουν τις υποβολές τους με υπογεγραμμένες εκδόσεις. Τέλος, πρέπει να βεβαιωθούμε ότι καταλαβαίνουμε το GPG και τα οφέλη από της υπογραφής πριν την υιοθετήσουμε ως μέρος της τυποποιημένης ροής εργασίας μας.