Commits signieren
Lerne, Git-Commits und Tags kryptografisch mit GPG oder SSH zu signieren, um Autorschaft zu beweisen und das Verified-Badge zu erhalten.
Das Signieren eines Commits fügt eine kryptografische Signatur hinzu, die beweist, wer ihn erstellt hat und dass sein Inhalt nicht verändert wurde. Dieses Kapitel erklärt, warum Signaturen wichtig sind, wie man einen Schlüssel generiert, wie man Commits und Tags mit GPG oder SSH signiert, wie man Signaturen verifiziert und wie man die Fehler behebt, auf die man beim ersten Mal wahrscheinlich stößt.
Was das Signieren tatsächlich beweist
Standardmäßig sind der Autorenname und die E-Mail-Adresse eines Commits nur Text. Git prüft diese nie — jeder kann user.name und user.email auf beliebige Werte setzen (siehe git config) und einen Commit erstellen, der vorgibt, von jemand anderem zu stammen. Eine Signatur ändert das: Sie wird mit einem privaten Schlüssel erstellt, den nur du besitzt, und jeder mit deinem passenden öffentlichen Schlüssel kann zwei Dinge bestätigen:
- Autorschaft — der Commit stammt wirklich vom Inhaber dieses privaten Schlüssels.
- Integrität — wenn ein einzelnes Byte des Commits (Nachricht, Tree, Eltern-Commit, Autor) geändert wird, schlägt die Verifizierung fehl.
Für Projekte, bei denen die Herkunft wichtig ist — sicherheitskritischer Code, Open-Source-Releases, regulierte Umgebungen — ermöglicht eine signierte Historie Gutachtern zu vertrauen, wer was geschrieben hat. Auf GitHub und GitLab erhält eine verifizierte Signatur ein grünes Verified-Badge neben dem Commit.
GPG oder SSH wählen
Git unterstützt zwei Signaturformate. Wähle eines:
- GPG (OpenPGP) — die traditionelle Wahl. Ausgereift, weit verbreitet, aber die Schlüsselverwaltung (Schlüsselbunde, Ablauf, der
gpg-Agent) hat eine Lernkurve. - SSH — verfügbar seit Git 2.34. Wenn du bereits einen SSH-Schlüssel zum Pushen verwendest, kannst du ihn zum Signieren mit fast keinem zusätzlichen Aufwand wiederverwenden. Einfacher zu verwalten und für die meisten Menschen heutzutage der empfohlene Einstiegspunkt.
Prüfe zuerst deine Version:
git --versionMit GPG signieren
Schlüssel generieren oder finden
Wenn du noch keinen GPG-Schlüssel hast, erstelle einen (übernimm die Standardwerte und wähle einen 4096-Bit-RSA- oder einen ECC-Schlüssel):
gpg --full-generate-keyListe deine Schlüssel auf und kopiere die lange Schlüssel-ID — den Wert nach dem Algorithmus in der sec-Zeile:
gpg --list-secret-keys --keyid-format=longsec ed25519/3AA5C34371567BD2 2024-01-08 [SC]
AB1C2D3E...
uid Jane Dev <[email protected]>Hier ist die Schlüssel-ID 3AA5C34371567BD2.
Git konfigurieren
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign trueEinen Commit oder Tag signieren
Wenn commit.gpgsign aktiviert ist, wird jeder Commit automatisch signiert. Um einen einzelnen Commit explizit zu signieren, verwende das großgeschriebene -S-Flag:
git commit -S -m "Add audited payment handler"Um einen annotierten Tag zu signieren, verwende das kleingeschriebene -s:
git tag -s v2.0.0 -m "Signed release 2.0.0"-S (Großbuchstabe) signiert einen Commit, während -s (Kleinbuchstabe) einen Tag signiert. Bei git commit fügt das kleingeschriebene -s stattdessen eine Signed-off-by-Zeile hinzu — ein Klartextnachweis (Developer Certificate of Origin), keine kryptografische Signatur.Mit SSH signieren
Wenn du einen id_ed25519-Schlüssel (oder einen anderen SSH-Schlüssel) hast, weise Git auf den öffentlichen Schlüssel hin und wechsle das Signaturformat:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign trueCommits und Tags werden nun mit denselben -S / -s-Flags wie zuvor signiert — keine weitere Änderung erforderlich.
Lokale Verifizierung für SSH aktivieren
Im Gegensatz zu GPG hat Git keinen eingebauten Vertrauensspeicher für SSH-Schlüssel, daher meldet git log --show-signature No principal matched, bis du eine Datei mit erlaubten Signierern erstellst. Ordne jeder E-Mail-Adresse ihren öffentlichen Schlüssel zu:
mkdir -p ~/.config/git
echo "[email protected] $(cat ~/.ssh/id_ed25519.pub)" >> ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signersDeinen öffentlichen Schlüssel beim Host hochladen
Das Verified-Badge erscheint erst, nachdem der Host deinen öffentlichen Schlüssel hinterlegt hat.
- GPG: Kopiere den gepanzerten öffentlichen Schlüssel aus
gpg --armor --export <key-id>und füge ihn unter Settings → SSH and GPG keys → New GPG key ein. - SSH: Füge den Inhalt von
~/.ssh/id_ed25519.pubals Schlüssel vom Typ Signing key (getrennt von einem Authentifizierungsschlüssel) im selben Einstellungsbereich hinzu.
Die E-Mail-Adresse auf deinem Schlüssel muss mit der Autor-E-Mail des Commits übereinstimmen, sonst zeigt der Host Unverified an.
Signaturen verifizieren
Prüfe Signaturen lokal mit einem dieser Befehle:
git log --show-signature # show signature status in the log
git verify-commit HEAD # verify one commit
git verify-tag v2.0.0 # verify a tagFür eine kompakte Ansicht gibt der %G?-Platzhalter in git log einen einzelnen Statuscode pro Commit aus:
git log --pretty="%h %G? %s"a1b2c3d G Add audited payment handler
d4e5f6g N Quick typo fixG bedeutet eine gute (gültige) Signatur, B schlecht, U gut mit unbekannter Gültigkeit und N keine Signatur.
Häufige Fehler und Lösungen
error: gpg failed to sign the data— normalerweise kann der GPG-Agent nicht nach deiner Passphrase fragen. Exportiere das Terminal, das er verwenden soll:export GPG_TTY=$(tty)(füge es zu~/.bashrcoder~/.zshrchinzu). Unter macOS installierepinentry-mac, damit der Agent einen Passwort-Dialog öffnen kann.gpg: signing failed: No secret key—user.signingkeyzeigt auf die falsche ID. Prüfe erneut mitgpg --list-secret-keys --keyid-format=long.- GitHub zeigt Unverified — die Autor-E-Mail des Commits stimmt nicht mit einer E-Mail überein, die mit deinem hochgeladenen Schlüssel verknüpft ist, oder der Schlüssel wurde nicht beim Host hinzugefügt.
No principal matched(SSH) — du hastgpg.ssh.allowedSignersFilenicht eingerichtet (siehe oben).
Häufige Optionen
| Befehl | Beschreibung |
|---|---|
git commit -S | Signiert einen einzelnen Commit. |
git tag -s <name> | Erstellt einen signierten annotierten Tag. |
git config commit.gpgsign true | Signiert jeden Commit automatisch. |
git config gpg.format ssh | Mit einem SSH-Schlüssel statt GPG signieren. |
git log --show-signature | Zeigt den Signaturstatus im Log an. |
git log --pretty="%G?" | Gibt einen Signaturstatuscode pro Commit aus. |
git verify-commit <commit> | Verifiziert die Signatur eines Commits. |
git verify-tag <tag> | Verifiziert die Signatur eines Tags. |