Passkeys: Was zum Teufel und warum?

Avatar of Neal Fennimore
Neal Fennimore am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Diese Dinge namens Passkeys machen gerade die Runde. Sie waren ein Hauptanziehungspunkt bei W3C TPAC 2022, erhielten Unterstützung in Safari 16, finden ihren Weg in macOS und iOS und sind dazu bestimmt, die Zukunft für Passwortmanager wie 1Password zu sein. Sie werden bereits in Android unterstützt und werden bald auch in Chrome OS und Windows in zukünftigen Versionen Einzug halten.

Geekige OS-Sicherheitsverbesserungen machen in der Front-End-Community keine großen Schlagzeilen, aber es liegt nahe, dass Passkeys ein "Ding" sein werden. Und angesichts der Tatsache, wie Passwörter und Passwort-Apps die Benutzererfahrung bei Dingen wie Authentifizierung und Formularverarbeitung beeinflussen, wollen wir uns vielleicht zumindest damit auseinandersetzen, damit wir wissen, was kommt.

Das ist der Sinn dieses Artikels. Ich studiere und experimentiere schon seit einiger Zeit mit Passkeys – und der WebAuthn-API, auf der sie aufbauen. Lassen Sie mich teilen, was ich gelernt habe.

Inhaltsverzeichnis

Terminologie

Hier ist der obligatorische Abschnitt mit der Terminologie, die Sie kennen sollten, wenn wir tiefer eintauchen. Wie die meisten technischen Begriffe ist Passkeys mit esoterischem Kauderwelsch und Akronymen durchsetzt, die oft Hürden für das Verständnis darstellen. Ich werde versuchen, einige davon hier für Sie zu entmystifizieren.

  • Relying Party (Vertrauende Partei): der Server, gegen den Sie sich authentifizieren werden. Wir verwenden in diesem Artikel "Server", um die Relying Party zu meinen.
  • Client: in unserem Fall der Webbrowser oder das Betriebssystem.
  • Authenticator (Authentifikator): Software und/oder Hardware-Geräte, die die Generierung und Speicherung von öffentlichen Schlüsselpaaren ermöglichen.
  • FIDO: Eine Organisation für offene Standards, die auch Spezifikationen für FIDO-Credentials erstellt.
  • WebAuthn: Das zugrundeliegende Protokoll für Passkeys, auch bekannt als FIDO2 -Credential oder Single-Device-FIDO-Credentials.
  • Passkeys: WebAuthn, aber mit Cloud-Synchronisierung (auch als Multi-Device-FIDO-Credentials, Discoverable Credentials oder Resident Credentials bezeichnet).
  • Public Key Cryptography (Public-Key-Kryptographie): Ein generiertes Schlüsselpaar, das einen privaten und einen öffentlichen Schlüssel enthält. Abhängig vom Algorithmus sollte es entweder zum Signieren und Verifizieren oder zum Verschlüsseln und Entschlüsseln verwendet werden. Dies ist auch bekannt als asymmetrische Kryptographie.
  • RSA: Ein Akronym der Namen der Erfinder, Rivest Shamir und Adel. RSA ist eine ältere, aber immer noch nützliche Familie der Public-Key-Kryptographie, die auf der Primfaktorzerlegung basiert.
  • Elliptic Curve Cryptography (ECC - Elliptische-Kurven-Kryptographie): Eine neuere Familie von Kryptographie, die auf elliptischen Kurven basiert.
  • ES256: Ein elliptischer Public Key, der einen ECDSA-Signaturalgorithmus (PDF) mit SHA256 zum Hashing verwendet.
  • RS256: Ähnlich wie ES256, verwendet jedoch RSA mit RSASSA-PKCS1-v1.5 und SHA256.

Was sind Passkeys?

Bevor wir speziell über Passkeys sprechen können, müssen wir über ein anderes Protokoll namens WebAuthn (auch bekannt als FIDO2) sprechen. Passkeys sind eine Spezifikation, die auf WebAuthn aufbaut. WebAuthn ermöglicht es, Passwörter durch Public-Key-Kryptographie zu ersetzen. Wir verwenden eine Art Sicherheitsgerät, wie z. B. einen Hardware-Schlüssel oder ein Trusted Platform Module (TPM), um private und öffentliche Schlüssel zu erstellen.

Der öffentliche Schlüssel ist für jeden verwendbar. Der private Schlüssel kann jedoch nicht von dem Gerät entfernt werden, das ihn generiert hat. Dies war eines der Probleme mit WebAuthn; wenn Sie das Gerät verlieren, verlieren Sie den Zugriff.

Passkeys löst dieses Problem, indem es eine Cloud-Synchronisierung Ihrer Anmeldedaten bietet. Mit anderen Worten: Was Sie auf Ihrem Computer generieren, kann jetzt auch auf Ihrem Telefon verwendet werden (obwohl es verwirrenderweise auch Single-Device-Credentials gibt).

Derzeit, zum Zeitpunkt des Schreibens, bieten nur iOS, macOS und Android vollständige Unterstützung für Cloud-synchronisierte Passkeys, und selbst dann sind sie durch den verwendeten Browser eingeschränkt. Google und Apple stellen Schnittstellen für die Synchronisierung über ihre Google Passwortmanager und Apple iCloud Keychain -Dienste bereit.

Wie ersetzen Passkeys Passwörter?

In der Public-Key-Kryptographie können Sie etwas tun, das als Signieren bekannt ist. Beim Signieren wird ein Stück Daten genommen und mit dem privaten Schlüssel durch einen Signaturalgorithmus laufen gelassen, wo es dann mit dem öffentlichen Schlüssel verifiziert werden kann.

Jeder kann ein öffentliches Schlüsselpaar generieren, und es ist keiner Person zuordenbar, da jeder es ursprünglich hätte generieren können. Nützlich ist, dass nur mit dem privaten Schlüssel signierte Daten mit dem öffentlichen Schlüssel verifiziert werden können. Das ist der Teil, der ein Passwort ersetzt – ein Server speichert den öffentlichen Schlüssel, und wir melden uns an, indem wir verifizieren, dass wir die andere Hälfte (z. B. den privaten Schlüssel) besitzen, indem wir eine zufällige Herausforderung signieren.

Als zusätzlichen Vorteil, da wir die öffentlichen Schlüssel des Benutzers in einer Datenbank speichern, gibt es keine Sorge mehr, dass Passwort-Leaks Millionen von Benutzern betreffen. Dies reduziert Phishing, Leaks und eine Reihe anderer Sicherheitsprobleme, mit denen unsere passwortabhängige Welt derzeit konfrontiert ist. Wenn eine Datenbank gehackt wird, sind nur die öffentlichen Schlüssel des Benutzers gespeichert, was sie für einen Angreifer praktisch nutzlos macht.

Keine vergessenen E-Mails und die zugehörigen Passwörter mehr! Der Browser erinnert sich, welche Anmeldedaten Sie für welche Website verwendet haben – Sie müssen nur ein paar Klicks machen und schon sind Sie angemeldet. Sie können eine sekundäre Überprüfungsmethode für die Verwendung des Passkeys bereitstellen, z. B. biometrische Daten oder eine PIN, aber diese sind immer noch viel schneller als die Passwörter von gestern.

Mehr über Kryptographie

Public-Key-Kryptographie beinhaltet das Vorhandensein eines privaten und eines öffentlichen Schlüssels (bekannt als Schlüsselpaar). Die Schlüssel werden zusammen generiert und haben unterschiedliche Verwendungszwecke. Zum Beispiel ist der private Schlüssel dazu bestimmt, geheim gehalten zu werden, und der öffentliche Schlüssel ist für jeden bestimmt, mit dem Sie Nachrichten austauschen möchten.

Beim Verschlüsseln und Entschlüsseln einer Nachricht wird der öffentliche Schlüssel des Empfängers verwendet, um eine Nachricht zu verschlüsseln, so dass nur der private Schlüssel des Empfängers die Nachricht entschlüsseln kann. Im Fachjargon der Sicherheit wird dies als "Bereitstellung von Vertraulichkeit" bezeichnet. Dies bietet jedoch keinen Beweis dafür, dass der Absender derjenige ist, für den er sich ausgibt, da jeder potenziell einen öffentlichen Schlüssel verwenden kann, um jemandem eine verschlüsselte Nachricht zu senden.

Es gibt Fälle, in denen wir überprüfen müssen, ob eine Nachricht tatsächlich von ihrem Absender stammt. In diesen Fällen verwenden wir Signieren und Signaturprüfung, um sicherzustellen, dass der Absender derjenige ist, für den er sich ausgibt (auch bekannt als Authentizität). In der Public-Key-Kryptographie (auch asymmetrische Kryptographie genannt) geschieht dies im Allgemeinen durch das Signieren des Hashs einer Nachricht, so dass nur der öffentliche Schlüssel ihn korrekt verifizieren kann. Der Hash und der private Schlüssel des Absenders erzeugen nach der Verarbeitung durch einen Algorithmus eine Signatur, und dann kann jeder mit dem öffentlichen Schlüssel des Absenders überprüfen, dass die Nachricht vom Absender stammt.

Wie greifen wir auf Passkeys zu?

Um auf Passkeys zuzugreifen, müssen wir sie zuerst generieren und irgendwo speichern. Ein Teil dieser Funktionalität kann durch einen Authentifikator bereitgestellt werden. Ein Authentifikator ist jedes Hardware- oder Software-gestützte Gerät, das die Erzeugung kryptographischer Schlüssel ermöglicht. Denken Sie an diese Einmalpasswörter, die Sie von Google Authenticator1Password oder LastPass erhalten, unter anderem.

Ein Software-Authentifikator kann beispielsweise das Trusted Platform Module (TPM) oder die Secure Enclave eines Geräts verwenden, um Anmeldedaten zu erstellen. Die Anmeldedaten können dann remote gespeichert und geräteübergreifend synchronisiert werden, z. B. Passkeys. Ein Hardware-Authentifikator wäre etwas wie ein YubiKey, der Schlüssel auf dem Gerät selbst generieren und speichern kann.

Um auf den Authentifikator zuzugreifen, muss der Browser Zugriff auf die Hardware haben, und dafür benötigen wir eine Schnittstelle. Die hier verwendete Schnittstelle ist das Client to Authenticator Protocol (CTAP). Es ermöglicht den Zugriff auf verschiedene Authentifikatoren über verschiedene Mechanismen. Zum Beispiel können wir über NFC, USB und Bluetooth auf einen Authentifikator zugreifen, indem wir CTAP verwenden.

Eine der interessanteren Möglichkeiten, Passkeys zu nutzen, ist die Verbindung Ihres Telefons über Bluetooth mit einem anderen Gerät, das Passkeys möglicherweise nicht unterstützt. Wenn die Geräte über Bluetooth gekoppelt sind, kann ich mich im Browser auf meinem Computer anmelden, indem ich mein Telefon als Vermittler verwende!

Der Unterschied zwischen Passkeys und WebAuthn

Passkeys und WebAuthn-Schlüssel unterscheiden sich in mehrfacher Hinsicht. Erstens gelten Passkeys als Multi-Device-Credentials und können geräteübergreifend synchronisiert werden. Im Gegensatz dazu sind WebAuthn-Schlüssel Single-Device-Credentials – eine schicke Art zu sagen, dass Sie für die Verifizierung an ein Gerät gebunden sind.

Zweitens müssen WebAuthn-Schlüssel zur Authentifizierung bei einem Server den User-Handle für die Anmeldung bereitstellen, wonach eine allowCredentials-Liste vom Server an den Client zurückgegeben wird, die angibt, welche Credentials verwendet werden können, um sich anzumelden. Passkeys überspringen diesen Schritt und verwenden den Domainnamen des Servers, um anzuzeigen, welche Schlüssel bereits an diese Website gebunden sind. Sie können den Passkey auswählen, der mit diesem Server verknüpft ist, da er Ihrem System bereits bekannt ist.

Ansonsten sind die Schlüssel kryptographisch gleich; sie unterscheiden sich nur in der Art und Weise, wie sie gespeichert werden und welche Informationen sie verwenden, um den Anmeldevorgang zu starten.

Der Prozess... kurz gesagt

Der Prozess zur Generierung eines WebAuthn- oder eines Passkeys ist sehr ähnlich: Sie erhalten eine Herausforderung vom Server und verwenden dann die Web-API navigator.credentials.create, um ein öffentliches Schlüsselpaar zu generieren. Anschließend senden Sie die Herausforderung und den öffentlichen Schlüssel zurück an den Server, um sie zu speichern.

Nach Erhalt des öffentlichen Schlüssels und der Herausforderung validiert der Server die Herausforderung und die Sitzung, aus der sie erstellt wurde. Wenn dies erfolgreich ist, werden der öffentliche Schlüssel sowie alle anderen relevanten Informationen wie die Benutzerkennung oder Attestierungsdaten in der Datenbank gespeichert.

Der Benutzer hat einen weiteren Schritt – er fordert eine weitere Herausforderung vom Server an und verwendet die API navigator.credentials.get, um die Herausforderung zu signieren. Wir senden die signierte Herausforderung zurück an den Server, und der Server verifiziert die Herausforderung und loggt uns dann ein, wenn die Signatur erfolgreich ist.

Natürlich steckt hinter jedem Schritt noch einiges mehr. Aber so würden wir uns im Allgemeinen bei einer Website mit WebAuthn oder Passkeys anmelden.

Das Wesentliche

Passkeys werden in zwei verschiedenen Phasen verwendet: der Attestation (Attestierung) und der Assertion (Behauptung) Phase.

Die Attestierungsphase kann auch als Registrierungsphase betrachtet werden. Sie würden sich mit einer E-Mail und einem Passwort für eine neue Website registrieren, aber in diesem Fall würden wir unseren Passkey verwenden.

Die Assertionsphase ähnelt dem Anmelden bei einer Website nach der Registrierung.

Attestierung

Größere Ansicht

Die API navigator.credentials.create steht im Mittelpunkt unserer Attestierungsphase. Wir werden als neuer Benutzer im System registriert und müssen ein neues Public-Key-Paar generieren. Wir müssen jedoch angeben, welche Art von Schlüsselpaar wir generieren möchten. Das bedeutet, wir müssen Optionen an navigator.credentials.create übergeben.

// The `challenge` is random and has to come from the server
const publicKey: PublicKeyCredentialCreationOptions = {
  challenge: safeEncode(challenge),
  rp: {
    id: window.location.host,
    name: document.title,
  },
  user: {
    id: new TextEncoder().encode(crypto.randomUUID()), // Why not make it random?
    name: 'Your username',
    displayName: 'Display name in browser',
  },
  pubKeyCredParams: [
    {
      type: 'public-key',
      alg: -7, // ES256
    },
    {
      type: 'public-key',
      alg: -256, // RS256
    },
  ],
  authenticatorSelection: {
    userVerification: 'preferred', // Do you want to use biometrics or a pin?
    residentKey: 'required', // Create a resident key e.g. passkey
  },
  attestation: 'indirect', // indirect, direct, or none
  timeout: 60_000,
};
const pubKeyCredential: PublicKeyCredential = await navigator.credentials.create({
  publicKey
});
const {
  id // the key id a.k.a. kid
} = pubKeyCredential;
const pubKey = pubKeyCredential.response.getPublicKey();
const { clientDataJSON, attestationObject } = pubKeyCredential.response;
const { type, challenge, origin } = JSON.parse(new TextDecoder().decode(clientDataJSON));
// Send data off to the server for registration

Wir erhalten PublicKeyCredential, das eine AuthenticatorAttestationResponse enthält, die nach der Erstellung zurückkommt. Das Credential hat die ID des generierten Schlüsselpaars.

Die Antwort liefert einige nützliche Informationen. Erstens haben wir unseren öffentlichen Schlüssel in dieser Antwort und müssen ihn an den Server senden, um ihn zu speichern. Zweitens erhalten wir auch die Eigenschaft clientDataJSON, die wir dekodieren können, und daraus die typechallenge und origin des Passkeys abrufen.

Für die Attestierung wollen wir die typechallenge und origin auf dem Server validieren, sowie den öffentlichen Schlüssel mit seiner ID, z. B. kid, speichern. Wir können optional auch das attestationObject speichern, wenn wir möchten. Eine weitere nützliche Eigenschaft zum Speichern ist der COSE-Algorithmus, der oben in unseren PublicKeyCredentialCreationOptions mit alg: -7 oder alg: -256 definiert ist, um später signierte Herausforderungen in der Assertionsphase einfach verifizieren zu können.

Behauptung

Größere Ansicht

Die API navigator.credentials.get wird im Mittelpunkt der Assertionsphase stehen. Konzeptionell wäre dies der Punkt, an dem sich der Benutzer nach der Registrierung bei der Webanwendung anmeldet.

// The `challenge` is random and has to come from the server
const publicKey: PublicKeyCredentialRequestOptions = {
  challenge: new TextEncoder().encode(challenge),
  rpId: window.location.host,
  timeout: 60_000,
};
const publicKeyCredential: PublicKeyCredential = await navigator.credentials.get({
  publicKey,
  mediation: 'optional',
});
const {
  id // the key id, aka kid
} = pubKeyCredential;
const { clientDataJSON, attestationObject, signature, userHandle } = pubKeyCredential.response;
const { type, challenge, origin } = JSON.parse(new TextDecoder().decode(clientDataJSON));
// Send data off to the server for verification

Wir erhalten wieder ein PublicKeyCredential mit einer AuthenticatorAssertionResponse diesmal. Das Credential enthält wieder die Schlüsselkennung.

Wir erhalten auch wieder die typechallenge und origin aus der clientDataJSON. Die signature ist nun in der Antwort enthalten, ebenso wie die authenticatorData. Wir benötigen diese und die clientDataJSON, um zu verifizieren, dass dies mit dem privaten Schlüssel signiert wurde.

Die authenticatorData enthält einige Eigenschaften, die es wert sind, verfolgt zu werden. Erstens ist dies der SHA256-Hash des verwendeten Ursprungs, der sich in den ersten 32 Bytes befindet und nützlich ist, um zu verifizieren, dass die Anfrage vom selben Ursprungsserver stammt. Zweitens ist die signCount, die von Byte 33 bis 37 reicht. Diese wird vom Authentifikator generiert und sollte mit ihrem vorherigen Wert verglichen werden, um sicherzustellen, dass mit dem Schlüssel nichts Ungewöhnliches geschieht. Der Wert sollte immer 0 sein, wenn es sich um einen Multi-Device-Passkey handelt, und zufällig größer als der vorherige signCount, wenn es sich um einen Single-Device-Passkey handelt.

Sobald Sie Ihre Anmeldung bestätigt haben, sollten Sie angemeldet sein – Herzlichen Glückwunsch! Passkeys ist ein ziemlich großartiges Protokoll, aber es hat einige Einschränkungen.

Einige Nachteile

Es gibt viele Vorteile für Passkeys, aber zum Zeitpunkt der Erstellung dieses Artikels gibt es einige Probleme damit. Erstens ist die Unterstützung für Passkeys noch etwas früh, mit nur Single-Device-Credentials unter Windows und sehr geringer Unterstützung für Linux-Systeme.  Passkeys.dev bietet eine nette Tabelle, die so etwas wie das Caniuse dieses Protokolls ist.

Außerdem kommunizieren die Passkey-Plattformen von Google und Apple nicht miteinander. Wenn Sie Ihre Anmeldedaten von Ihrem Android-Telefon auf Ihr iPhone übertragen möchten... nun, für den Moment haben Sie Pech gehabt. Das heißt nicht, dass es keine Interoperabilität gibt! Sie können sich auf Ihrem Computer anmelden, indem Sie Ihr Telefon als Authentifikator verwenden. Aber es wäre viel sauberer, es einfach im Betriebssystem integriert und synchronisiert zu haben, ohne dass es auf dem Vendor-Level gesperrt ist.

Wohin geht die Reise?

Wie sieht das Passkey-Protokoll der Zukunft aus? Es sieht ziemlich gut aus! Sobald es Unterstützung von mehr Betriebssystemen erhält, sollte es eine Zunahme der Nutzung geben und Sie werden es immer häufiger im Einsatz sehen. Einige Passwortmanager werden sie sogar direkt unterstützen.

Passkeys sind keineswegs nur im Web unterstützt.  Android und iOS werden native Passkeys als First-Class-Bürger unterstützen. Wir stecken noch in den Kinderschuhen, aber erwarten Sie, dass es immer häufiger erwähnt wird.

Schließlich eliminieren wir die Notwendigkeit von Passwörtern und machen die Welt dadurch sicherer!

Ressourcen

Hier sind einige weitere Ressourcen, wenn Sie mehr über Passkeys erfahren möchten. Es gibt auch ein Repository und eine Demo, die ich für diesen Artikel zusammengestellt habe.