- Sicherheitstoken signieren innerhalb des Geräts, ohne den privaten Schlüssel nach außen zu geben, und verlangen eine physische Aktion des Nutzers, sodass es für Remote-Angreifer schwer ist, beliebige Signaturen zu erzeugen
- Sie lassen sich für SSH-Authentifizierung, U2F, passwortlose lokale Anmeldung,
sudo und das Signieren von git-Commits verwenden, und die eingebauten Sicherheitsmodule moderner Laptops und Smartphones können einen YubiKey ersetzen
- Die mit
ssh-keygen -t ed25519-sk erzeugte „Privatschlüssel“-Datei ist kein echter privater Schlüssel, sondern ein Handle, das auf den Schlüssel im Token zeigt; mit demselben Token kann man auf anderen Computern dieselbe SSH-Schlüsseldatei erzeugen
- Auf dem MacBook ließ sich das Secure Element als SSH-Schlüssel einrichten, sodass Touch-ID-basierte SSH-Anmeldungen möglich waren; für git-Commit-Signaturen war statt eines Dateipfads
ssh-agent und ein user.signingKey im Format key:: nötig
- Sicherheitstoken erlauben bei Verlust keine Wiederherstellung des privaten Schlüssels und bergen ein Usability-Risiko durch häufiges Tippen; auf Windows-Laptops konnte Windows Hello die Nutzung des SSH-Schlüssels per Gesichtserkennung, Fingerabdruck oder PIN bestätigen
Vorteile und Grenzen von Sicherheitstoken
-
Die Kernarchitektur gegen Remote-Angriffe
- Ein Sicherheitstoken ist ein Gerät, das ein Schlüsselpaar aus privatem und öffentlichem Schlüssel im Gerät hält; der öffentliche Schlüssel lässt sich leicht auslesen, aber der private Schlüssel verlässt das Gerät nicht
- Schickt man ein zu signierendes Datenpaket an das Gerät, wird es darin mit dem privaten Schlüssel signiert; normalerweise ist dafür zusätzlich eine physische Aktion des Nutzers nötig, etwa das Drücken eines blinkenden Touch-Buttons
- Selbst wenn ein Remote-Angreifer Zugriff auf den Computer erhält, kann das Sicherheitstoken keine beliebigen Signaturen erzeugen, solange der Nutzer nicht in der realen Welt aktiv wird; deshalb wirkt es sicherer, als ein vollständiges SSH-Schlüsselpaar als Dateien im Verzeichnis
~/.ssh zu speichern
- Mit SoloKeys und Nitrokeys gibt es auch Optionen für Nutzer, die FOSS-Firmware möchten
- Hochwertigere Sicherheitstoken ergänzen biometrische Funktionen wie eingebaute Fingerabdruckleser, aber der Kern bleibt, dass der private Schlüssel das Gerät nicht verlässt
-
Risiken bei der Benutzbarkeit
- Wenn sich Nutzer daran gewöhnen, bei jedem Blinken des Sicherheitstokens zu drücken, reagieren sie womöglich auch auf bösartige Anfragen gedankenlos
- Bei fortlaufenden Signaturvorgängen, in denen das Token wiederholt gedrückt werden muss, ist es schwer, eine zusätzliche blinkende Anfrage tatsächlich zu bemerken
- Apple und Microsoft nutzen in Authenticator-Apps auf Smartphones ein Verfahren, bei dem bei jedem Zugriffsversuch ein zufälliger Zahlencode angezeigt wird, den der Nutzer eingeben muss; das ist jedoch umständlich und verringert den Usability-Vorteil von Sicherheitstoken gegenüber Apps wie Authy oder Google Authenticator mit TOTP
-
Verlust und Backup-Probleme
- Geht ein Sicherheitstoken verloren, ist der betreffende private Schlüssel dauerhaft weg und lässt sich nicht sichern
- Um das Risiko zu vermeiden, aus mehreren Konten ausgesperrt zu werden, sollte man beim Kauf von Sicherheitstoken mindestens zwei Geräte anschaffen und beim selben Dienst registrieren
- Als Alternative gibt es Backup- und Wiederherstellungsverfahren wie BIP 39, bei denen ein privater Schlüssel in eine für Menschen lesbare Wortliste umgewandelt und notiert wird
- Wenn ein privater Schlüssel die Secure Enclave verlassen kann, werden auch Phishing-Angriffe möglich, die Nutzer dazu verleiten, die Wortliste an der falschen Stelle einzugeben
- Wenn die Möglichkeit, alle Sicherheitstoken zu verlieren, große Sorgen bereitet, kann eine BIP-39-Wortliste das letzte Mittel sein, um den Systemzugang wiederherzustellen
Sicherheitstoken mit SSH und git verwenden
-
SSH-Privatschlüssel im Sicherheitstoken speichern
- Normalerweise erzeugt
ssh-keygen ein Dateipaar, das den vollständigen privaten Schlüssel enthält
- Um den privaten Schlüssel in einem Sicherheitstoken zu speichern, installiert man gemäß Yubicos FIDO/U2F-Anleitung libfido2 und führt mit eingestecktem Sicherheitstoken
ssh-keygen -t ed25519-sk aus
- Dabei wird ebenfalls ein Dateipaar erzeugt, aber die „Privatschlüssel“-Datei ist kein echter privater Schlüssel, sondern ein Handle auf den privaten Schlüssel im Sicherheitstoken
- Führt man
ssh-keygen -t ed25519-sk mit demselben Sicherheitstoken erneut aus, kann man auf jedem Computer dieselben privaten/öffentlichen Schlüsseldateien erzeugen; der SSH-Zugang wandert also mit dem Sicherheitstoken statt an eine bestimmte Datei auf einem bestimmten Computer gebunden zu sein
-
git-Authentifizierung und Commit-Signaturen
- Rund 90 % der Situationen, in denen das Sicherheitstoken gedrückt werden muss, entstehen durch git-Nutzung
- git-Forges implementieren SSH-Authentifizierung für Push- und Pull-Vorgänge; lädt man die oben erzeugte Datei
id_ed25519_sk.pub hoch, lässt sich das Schlüsselpaar des Sicherheitstokens zulassen
- git unterstützt auch SSH-Schlüssel für Commit-Signaturen; folgt man der GitHub-Dokumentation Einrichten eines Signaturschlüssels mit einem SSH-Schlüssel und führt anschließend
git config --global commit.gpgsign true aus, werden alle Commits automatisch signiert
- Damit eine git-Forge die Commits als eigene Signaturen erkennt, muss der öffentliche Schlüssel nochmals hochgeladen werden; dieses Feld ist meist vom Feld für SSH-Authentifizierung getrennt
-
Unbequemlichkeiten bei Commit-Signaturen
- Wenn man eine lange Commit-Liste rebased, müssen alle Commits erneut signiert werden
- Bei einem YubiKey mit Fingerabdruckleser war die Fehlerrate der Fingerabdruckerkennung zu hoch, um Dutzende Commits hintereinander zu signieren, sodass die Nutzung aufgegeben wurde
- Im „rebase/amend-zentrierten“ Wrapper jujutsu gibt es einen Ansatz, Commits erst beim Push zu signieren
-
Lokale Linux-Anmeldung und sudo
Das Secure Element eines MacBook als SSH-Schlüssel verwenden
- Wenn ein Sicherheitstoken dauerhaft im USB-C-Port steckt, ragt es wie ein kleiner Hebel hervor, der bei versehentlichem Fallenlassen oder Anstoßen sowohl Port als auch Token beschädigen kann
- Auf einem MacBook Air M1 von 2020 wurde nach der Anleitung von Arian van Putten das eingebaute Sicherheitselement als SSH-Schlüssel eingerichtet
sc_auth create-ctk-identity -l ssh -k p-256-ne -t bio
ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
- Dieser Befehl erzeugt ein privates/öffentliches Schlüsseldateipaar
id_ecdsa_sk_rk, das anschließend in das Verzeichnis ~/.ssh verschoben wird
- Auch hier ist die Privatschlüsseldatei kein echter privater Schlüssel, sondern ein Handle auf den Schlüssel im Gerät und kann daher in einer Form öffentlich eingefügt werden
- Um den öffentlichen Schlüssel auf einem Homelab-Server als authorized key hinzuzufügen, führt man Folgendes aus
ssh-copy-id -i ~/.ssh/id_ecdsa_sk_rk.pub <server nickname>
- Danach wird
~/.ssh/config um folgende Einstellungen ergänzt
Host *
IdentityFile ~/.ssh/id_ecdsa_sk_rk
SecurityKeyProvider=/usr/lib/ssh-keychain.dylib
- Führt man
ssh <server nickname> aus, zeigt macOS vor der Anmeldung automatisch eine Fingerabdruckabfrage an, danach läuft die SSH-Anmeldung normal weiter
git-Commit-Signaturen mit dem MacBook-Secure-Element
- Selbst wenn man
git config --global user.signingKey /Users/ahelwer/.ssh/id_ecdsa_sk_rk setzt und die Datei .ssh/allowed_signers aktualisiert, funktionieren git-Commit-Signaturen nicht sofort
- git scheitert beim Signieren von Commits und gibt einen Fehler wie
device not found? aus
error: Signing file /var/folders/l5/5wqvq2l10p96wtdtfr6lvrvw0000gn/T//.git_signing_buffer_tmpc4uQgO
Confirm user presence for key ECDSA-SK SHA256:oQDA2SNYb2MoSQcxJVSmWyAeAWPqMp7rxliBRfi87as
Couldn't sign message: device not found?
Signing /var/folders/l5/5wqvq2l10p96wtdtfr6lvrvw0000gn/T//.git_signing_buffer_tmpc4uQgO failed: device not found?
fatal: failed to write commit object
- Die Lösung besteht darin, ssh-agent zu verwenden, statt direkt auf die Dateien im Verzeichnis
~/.ssh zu verweisen
- Gemäß dem obigen Tutorial wird das Schlüsselpaar mit folgendem Befehl bei ssh-agent registriert
ssh-add -K -S /usr/lib/ssh-keychain.dylib
- Danach wird in
user.signingKey nicht ein Dateipfad eingetragen, sondern der Schlüssel selbst, also der Inhalt von ~/.ssh/id_ecdsa_sk_rk.pub mit vorangestelltem key::, in ~/.gitconfig
[user]
name = Andrew Helwer
signingKey = "key::sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGxFEdnIg6ppz+pQCdd1eisjOV4gxrjMv1Y4SbtdLoSm6CJCgPZ6q7lnNyuQQsdnS4/Tllsc656AQL7BO3OS47cAAAAEc3NoOg== ssh:"
- Nach dieser Konfiguration ließen sich Dateien mit dem Schlüssel im Secure Element des MacBook signieren und auf eine GitLab-Pages-Seite pushen
Ergebnisse unter Windows und Linux
- Auch auf einem vom Unternehmen bereitgestellten Windows-Laptop wurde ein kurzer Test durchgeführt
winget install Microsoft.OpenSSH.preview
ssh-keygen -t ecdsa-sk
- Auch dieser Befehl erzeugte ein privates/öffentliches Schlüsseldateipaar; bei SSH-Verbindungen akzeptierte der Standard-Login-Ablauf von Windows Hello Gesichtserkennung, Fingerabdruck oder PIN
- Unter Linux konnte dies nicht demonstriert werden, weil kein Zugriff auf einen Laptop mit angebundenem Secure Element und vergleichbarer Bestätigung der tatsächlichen Nutzerpräsenz verfügbar war
1 Kommentare
Lobste.rs-Kommentare
Großartiger Artikel, und schon allein darauf hinzuweisen, dass so etwas möglich ist, ist sehr wertvoll
Ich persönlich habe zwar nicht die richtige Library-Version gefunden, um das zum Laufen zu bringen, aber ich habe herausgefunden, dass 1Password 8 SSH-Schlüssel sicher speichern kann und der Agent das Entsperren des Schlüssels per biometrischer Authentifizierung unterstützt
Deshalb kann ich jetzt allein mit dem Finger git-Arbeit erledigen und mich auch bei SSH-Hosts anmelden
Anleitung: https://developer.1password.com/docs/ssh/get-started/
Das wirkt wie nur für Mac
Ein Linux-System mit einem solchen Sicherheitselement konnte ich nicht ausprobieren, und meine Linux-Workstation hat zwar ein V1-TPM, aber ich weiß nicht wirklich, wie man sicherstellt, dass Signaturvorgänge nur nach tatsächlicher Bestätigung der Benutzeranwesenheit ausgeführt werden
Vielleicht kann das jemand mit einem Linux-Laptop wie Framework ausprobieren. Möglicherweise funktioniert es sogar unter Asahi tatsächlich
Was genau befindet sich also in der bereitgestellten private key-Datei?
ssh:, also die Anwendung, entspricht der origin eines Passkeys und ist nützlich, wenn man resident keys pro Host oder Domain anlegtIch nutze das zum Beispiel, um selbst auf demselben physischen Yubikey Schlüssel nach Einsatzzweck zu trennen
flagslegt fest, wie die Hardware mit dem Schlüssel umgehen soll [1]. Der Agent kann zusätzlich eigene Einschränkungen hinzufügenTechnisch gesehen kann man im FIDO-Schlüssel auch andere Blobs oder Erweiterungen speichern, und bei meinem früheren Arbeitgeber haben wir das einmal genutzt, um zusammen mit der Authentifizierung zusätzliche Anmeldeinformationen wie einen öffentlichen X.509-Schlüssel zu übergeben. Ziemlich eleganter Ansatz
[1]
Der äußere Wrapper enthält den Magic-Wert
openssh-key-v1\0,cipher=none,kdf=none, ist also kein ChiffratDer 74-Byte-Blob des öffentlichen Schlüssels enthält den Schlüsseltyp
sk-ssh-ed25519@openssh.com, den 32-Byte-Ed25519-Punktfdcce889…03e7852bund die Anwendungssh:; dieser Wert trennt die FIDO-Credentials von SSH und WebAuthn per NamespaceDer private Abschnitt ist 248 Byte groß und wegen
cipher=noneKlartext. Enthalten sind der Zufallswertcheckint1 == checkint2 == 0x46744267, der wiederholte Schlüsseltyp und öffentliche Schlüssel, die Anwendungssh:sowieflags: 0x01Dieses Flag bedeutet
USER_PRESENCE_REQUIRED, also ist eine Berührung erforderlich, aber keine PIN/Benutzerverifizierung, und es ist ein nicht-residenter Schlüsselkey_handleist eine undurchsichtige 128-Byte-Credential-ID, die anauthenticatorGetAssertionübergeben wird und die das Gerät intern auflöst, um den Ed25519-Seed wiederherzustellenDaneben gibt es ein leeres
reserved, den Kommentarahelwer@ah-mbair.localund das Padding01 02 03Der Artikel scheint nur SSH zu behandeln, aber gibt es eine Möglichkeit, das Secure Enclave oder TPM meines Computers als FIDO2- oder U2F-Schlüssel zu verwenden?
Passkeys sind ebenfalls eine Form dieses Ansatzes, bei dem pro Website ein separater privater Schlüssel verwendet wird
Wenn man das sieht, wirkt es seltsam, dass Unterstützung für asymmetrische oder HMAC-API-Schlüssel, die an Hardware gebunden werden können, nicht verbreiteter ist
Es ist erfreulich zu sehen, dass immer mehr Spezifikationen in diese Richtung gehen, etwa WebAuthn, DBSC (Device-Bound Session Credentials) und OAuth2 DPOP