Ich benutze einen YubiKey als Zwei-Faktor-Authentifizierungs-Schlüssel und um meine Git-Commits zu signieren. Bis vor ein paar Tagen habe ich einen YubiKey 4 benutzt. Da mein aktueller Rechner keine USB-A-Anschlüsse hat, habe ich ständig USB-A-auf-USB-C-Adapter in meinem Rucksack herumjongliert, und den Key zu benutzen war im letzten Jahr ein ziemlicher Krampf. Deshalb habe ich beschlossen, dass es Zeit ist, auf meinen „neuen“ YubiKey 5C umzusteigen, damit ich nicht mehr mit diesen Adaptern hantieren muss.

Eigentlich habe ich den Key schon eine Weile, denn ich hatte ihn zusammen mit einem Ersatz-YubiKey-4 bestellt, wegen des Infineon-TPM-Problems, das sie damals festgestellt haben. Aber erst jetzt habe ich entschieden, dass es Zeit für den Wechsel auf den neuen Key ist.

Der andere Grund, es jetzt zu tun: Meine alten GPG-Keys sind abgelaufen und ich musste sie neu ausstellen, also kann ich den Key gleich zum Signieren meiner Git-Commits benutzen.

GPG-Wahnsinn

Wenn du schon einmal mit GPG-Keys zu tun hattest (oder gerade hast), weißt du, dass es ziemlich schwer sein kann, alles richtig und sicher zum Laufen zu bringen, wenn man es noch nie gemacht hat. Master-Keys offline halten, öffentliche Schlüssel hin- und herschieben, Keys nach dem Ablauf neu ausstellen, sie eventuell mit früheren Keys signieren, um sie zu verifizieren, Keys widerrufen … Selbst in der Theorie ist es nicht leicht, die Best Practices zu befolgen. In der Praxis wird es extrem kompliziert.

Die meisten Tutorials im Netz sagen, du sollst die CLI zum Erzeugen deiner Keys benutzen, dich durch Menüs mit einem ungewöhnlichen Bedienkonzept hangeln, und generell ist es eine Qual, das alles zum Laufen zu bringen. Die meisten Tutorials empfehlen einen Offline-Rechner wie einen Raspberry Pi und/oder Master-Key und Subkeys offline zu erzeugen und den Master-Key nicht auf deinem Rechner zu lassen.

🤯

Damit schlage ich mich jetzt seit fast 4 Jahren jeden Januar herum. Ich fürchte den Moment, in dem ich folgenden Fehler bekomme, der mir sagt, dass meine Signing-Keys abgelaufen sind.

error: gpg failed to sign the data
fatal: failed to write commit object

Dieses Jahr habe ich beschlossen, dass es Zeit ist, diesen Prozess deutlich einfacher zu machen und die eingebaute Schlüsselerzeugung zu nutzen, um den ganzen Ärger mit der GPG-Key-Generierung und Co. zu vermeiden.

Schlüsselerzeugung direkt auf dem YubiKey

Auch hier müssen wir die CLI-Oberfläche benutzen, aber sie ist etwas übersichtlicher, weil es weniger Schritte gibt.

Zuerst müssen wir unsere Karte bzw. unser Gerät einrichten.

Einrichtung von Karte/Gerät

Führe gpg --card-status im Terminal aus und du solltest in etwa Folgendes sehen:

Reader ………..: Yubico Yubikey 4 OTP U2F CCID
Application ID …: <Serial number>
Version ……….: 2.1
Manufacturer …..: Yubico
Serial number ….: <Device serial number>
Name of cardholder: unspecified
Language prefs …: en
Sex …………..: unspecified
URL of public key : \[not set\]
Login data …….: <e-mail or nothing>
Signature PIN ….: not forced
Key attributes …: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 9

Wenn du etwas Ähnliches siehst und keine Fehler auftauchen, kannst du weitermachen.

Führe gpg --card-edit aus.

Du landest in einer CLI-Oberfläche, die zu Beginn dieselben Informationen anzeigt und unten eine Eingabeaufforderung gpg/card> hat.

Tippe admin und drücke Return/Enter.

Mit help kannst du jetzt herausfinden, wie du die Besitzerinformationen und die PINs der Karte änderst.

Eines MUSST du tun: die Standard-PINs der Karte ändern. Es gibt zwei davon. Die erste ist die PIN, mit der du auf die Keys auf der Karte zugreifst. Die zweite ist die „Admin“-PIN oder PUK (Personal Unblocking Code).

Dazu tippst du passwd und siehst ein Menü:

gpg/card> passwd  
gpg: OpenPGP card no. <Serial number> detected

1 - change PIN  
2 - unblock PIN  
3 - change Admin PIN  
4 - set the Reset Code  
Q - quit

Tippe 1 und folge den Anweisungen, um deine PIN zu ändern. Die Standard-PIN ist 123456.

Wähle danach 3, um die Admin-PIN zu ändern. Der Standardwert ist 12345678.

Wenn beide PINs geändert sind, gehe zurück ins Hauptmenü, um die Key-Informationen fertig zu aktualisieren.

Die verfügbaren Befehle sind:

  • name – um den Namen des Karteninhabers zu ändern
  • login – um die E-Mail-Adresse oder den Login des Karteninhabers zu ändern

Danach können wir mit der eigentlichen Schlüsselerzeugung weitermachen.

Schlüsselerzeugung

Jetzt ist es Zeit, die Keys tatsächlich zu erzeugen.

Tippe dazu generate.

Du wirst gefragt: Make off-card backup of encryption key? (Y/n). Wie in der Dokumentation von YubiKey erwähnt, ist das aber nur ein Schein-Backup und erstellt kein vollständiges Backup der geheimen Schlüssel, daher spielt es keine Rolle, ob du mit Yes oder No antwortest. Ich antworte mit No(n).

Falls bereits Keys auf der Karte gespeichert sind, wirst du gefragt, ob du sie ersetzen willst:

gpg: Note: keys are already stored on the card!

Replace existing keys? (y/N)

Stelle sicher, dass du nichts Wichtiges ersetzt, wovon du kein Backup hast, und fahre mit Y fort. Wenn etwas Wichtiges drauf ist, brich den ganzen Vorgang besser mit Ctrl+C ab.

Du wirst nach der Karten-PIN gefragt, die du vorhin gesetzt hast.

Danach musst du auswählen, wie lange die Keys gültig sein sollen:

Please specify how long the key should be valid.
        0 = key does not expire
      <n> = key expires in n days
     <n>w = key expires in n weeks
     <n>m = key expires in n months
     <n>y = key expires in n years
 Key is valid for? (0)

Wenn die Keys nur 1 Jahr gültig sein sollen, tippe 1y.

Du wirst gebeten, das Ablaufdatum zu bestätigen. Prüfe, ob alles stimmt, und bestätige.

Danach wirst du aufgefordert, Informationen zum Key-Besitzer einzugeben:

Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: <Your name>
Email address: <Your e-mail>
Comment: <Comment is optional>
 You selected this USER-ID:
     "<Your name> <comment> <your e-mail>
 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

Type `O` to confirm if everything seems correct.

Dann wirst du nach deiner Admin-PIN bzw. PUK gefragt. Die wird gebraucht, weil auf die Karte geschrieben wird.

Wenn alles stimmt, beginnt der YubiKey zu blinken und tut das eine ganze Weile (bei mir etwa fünf Minuten).

Wenn er fertig ist, siehst du die folgende Meldung:

gpg: key <Short ID> marked as ultimately trusted
gpg: revocation certificate stored as '/Users/bisko/.gnupg/openpgp-revocs.d/<LONG ID>.rev' public and secret key created and signed.

Notiere dir die <Short ID>, wir brauchen sie später noch.

An diesem Punkt kannst du die GPG-Eingabeaufforderung mit quit oder Ctrl+C verlassen.

Jetzt ist es Zeit, den öffentlichen Schlüssel zu sichern, damit wir den Key auch auf einem anderen Rechner verwenden können.

Führe dazu den folgenden Befehl aus:

gpg --armor --export <Short ID> > <Short ID>.asc

Das exportiert den öffentlichen Schlüssel in eine Datei namens <Short ID>.asc. Die brauchst du später, wenn du den YubiKey auf einem anderen Rechner nutzen willst oder wenn du deine GPG-Konfiguration verlierst.

Um den öffentlichen Schlüssel in deinem Schlüsselbund wiederherzustellen, musst du Folgendes tun:

gpg --import < <Short ID>.asc
gpg: key <Short ID>: public key "Your Name <your@email>" imported
gpg: Total number processed: 1
gpg: imported: 1

Ein sehr wichtiger Hinweis. Wenn es eine frische GPG-Installation oder ein anderer Rechner ist, erkennt GPG die Keys auf der Karte nicht von selbst. Du musst gpg --card-status ausführen, damit GPG die Karte ausliest und die Keys darauf erkennt.

Git für das Signieren einrichten

Damit Git deine Commits signiert, musst du Folgendes zu deiner ~/.gitconfig hinzufügen.

Im Abschnitt [user] musst du die folgende Zeile hinzufügen (oder aktualisieren):

signingkey = 0x<Short ID>

Wenn du alle deine Commits signieren willst, füge am Ende der Datei Folgendes hinzu:

[gpg]
  program = /usr/local/bin/gpg
[commit]
  gpgsign = true

Damit signiert Git alle deine Commits.

Um GitHub einzurichten, musst du deinen öffentlichen Schlüssel zu deinem Profil hinzufügen. Gehe dazu auf GitHub -> Settings -> SSH and GPG keys -> New GPG key.

Dann siehst du ein Textfeld, in das du den gesamten Inhalt der oben erzeugten Datei <Short ID>.asc einfügen musst.

Wenn du den Inhalt der Datei kopieren willst (unter macOS), kannst du das hier tun:

cat <Short ID>.asc | pbcopy

Das kopiert den Inhalt der ganzen Datei in die Zwischenablage.

Füge ihn in das Textfeld auf GitHub ein und klicke auf den Button Add GPG key.

Danach kannst du einen Commit machen und zu GitHub pushen, und du solltest das hübsche Verified-Label sehen.

Debugging

Manchmal klappt nicht gleich alles. Um mehr Informationen zu sammeln, kannst du Folgendes versuchen:

Signieren mit GPG

Versuche zuerst, mit dem Key etwas zu signieren:

gpg -s <file>

Wenn das fehlschlägt, versuche herauszufinden, warum. Ich bin kein Experte und kann da nicht weiterhelfen.

Sieh dir die Ausgabe von Git anGIT_TRACE=1 git commit -am “test”

Das zeigt dir genau, was Git tut, während es versucht, den Commit durchzuführen und zu signieren. Es gibt dir einen Hinweis darauf, warum das Signieren fehlschlagen könnte.

Daran kannst du auch sehen, dass Git den folgenden Befehl ausführt:

/usr/local/bin/gpg --status-fd=2 -bsau <Key ID>

Du kannst versuchen, ihn manuell auszuführen, um vielleicht eine aussagekräftigere Fehlermeldung zu bekommen.