Start · Sprachen · JavaScript · Referenz · AuthenticatorAttestationResponse

AuthenticatorAttestationResponse

Schnittstelle

Enthält die Antwort des Authentifikators auf eine WebAuthn-Registrierung (<code>navigator.credentials.create()</code>): Attestierungsobjekt, Client-Daten und öffentlichen Schlüssel.

seit JavaScript Baseline: alle modernen Browser (Chrome 67+, Firef Kategorie: webapi

Signatur

interface AuthenticatorAttestationResponse extends AuthenticatorResponse

Beschreibung

AuthenticatorAttestationResponse ist das Objekt in der Eigenschaft response eines PublicKeyCredential, das navigator.credentials.create({ publicKey }) zurückgibt. Es entsteht bei der Registrierung eines neuen Passkeys bzw. Sicherheitsschlüssels und enthält alles, was der Server braucht, um den neuen öffentlichen Schlüssel zu prüfen und zu speichern.

Das Interface erbt von AuthenticatorResponse die Eigenschaft clientDataJSON (ein ArrayBuffer mit JSON, das type, challenge und origin enthält). Dazu kommen:

  • attestationObject – CBOR-kodiertes ArrayBuffer mit authData, Attestierungsformat (fmt) und Attestierungsaussage (attStmt).
  • getAuthenticatorData() – liefert die Authenticator-Daten als ArrayBuffer, ohne dass man CBOR selbst dekodieren muss.
  • getPublicKey() – liefert den öffentlichen Schlüssel im DER-kodierten SubjectPublicKeyInfo-Format (oder null, wenn der Algorithmus unbekannt ist).
  • getPublicKeyAlgorithm() – COSE-Algorithmus-ID als Zahl (z. B. -7 für ES256, -257 für RS256).
  • getTransports() – Array von Transportwegen wie "usb", "nfc", "ble", "internal", "hybrid".

Das Objekt lässt sich nicht selbst instanziieren; es wird ausschließlich vom Browser erzeugt. Im Praxisfall überträgt man die Binärdaten (Base64URL-kodiert) an den Server, der Challenge, Origin, RP-ID-Hash und ggf. die Attestierung verifiziert. Seit neueren Browsern liefert zudem PublicKeyCredential.prototype.toJSON() eine fertig serialisierbare Darstellung.

Rückgabewert

Typ
AuthenticatorAttestationResponse
Beschreibung
Wird über credential.response nach erfolgreichem navigator.credentials.create() bereitgestellt.

Beispiele

Passkey registrieren und Antwort auslesen

const registrieren = async () => {
  // Challenge sollte vom Server kommen – hier nur zur Demonstration lokal
  const challenge = crypto.getRandomValues(new Uint8Array(32));

  const credential = await navigator.credentials.create({
    publicKey: {
      challenge,
      rp: { name: 'Beispiel GmbH', id: location.hostname },
      user: {
        id: new TextEncoder().encode('user-4711'),
        name: 'max@example.com',
        displayName: 'Max Mustermann'
      },
      pubKeyCredParams: [
        { type: 'public-key', alg: -7 },   // ES256
        { type: 'public-key', alg: -257 }  // RS256
      ],
      authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' },
      attestation: 'none'
    }
  });

  const response = credential.response;
  console.log(response instanceof AuthenticatorAttestationResponse);
  console.log('Algorithmus:', response.getPublicKeyAlgorithm());
  console.log('Transporte:', response.getTransports());
};

registrieren().catch(err => console.error(err.name, err.message));
true Algorithmus: -7 Transporte: ["internal", "hybrid"]

clientDataJSON dekodieren und prüfen

const pruefeClientData = (response) => {
  const json = new TextDecoder().decode(response.clientDataJSON);
  const clientData = JSON.parse(json);
  console.log(clientData.type);   // muss 'webauthn.create' sein
  console.log(clientData.origin);
  return clientData;
};

// Nutzung: pruefeClientData(credential.response);
webauthn.create https://example.com

Antwort Base64URL-kodiert an den Server senden

const toBase64Url = (buffer) =>
  btoa(String.fromCharCode(...new Uint8Array(buffer)))
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');

const sendeRegistrierung = async (credential) => {
  const r = credential.response;
  const payload = {
    id: credential.id,
    rawId: toBase64Url(credential.rawId),
    type: credential.type,
    response: {
      clientDataJSON: toBase64Url(r.clientDataJSON),
      attestationObject: toBase64Url(r.attestationObject),
      transports: r.getTransports?.() ?? [],
      publicKey: r.getPublicKey ? toBase64Url(r.getPublicKey()) : null,
      publicKeyAlgorithm: r.getPublicKeyAlgorithm?.()
    }
  };

  const res = await fetch('/webauthn/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  });
  return res.ok;
};

// Wichtig · Fallstricke

  • Sicherheit: Die Verifikation muss immer serverseitig erfolgen. Challenge (einmalig, zufällig, vom Server erzeugt), origin, type === "webauthn.create" und der RP-ID-Hash in authData müssen geprüft werden – clientseitige Prüfungen sind wertlos, da manipulierbar.
  • WebAuthn funktioniert nur in einem sicheren Kontext (HTTPS oder localhost); in Cross-Origin-iframes nur mit der Permissions-Policy publickey-credentials-create.
  • attestationObject ist CBOR-kodiert – zum Auslesen benötigt man eine CBOR-Bibliothek oder nutzt die Hilfsmethoden getAuthenticatorData() und getPublicKey().
  • getPublicKey() gibt null zurück, wenn der Browser den Algorithmus nicht kennt; der Server sollte dann auf den COSE-Schlüssel in authData zurückfallen.
  • Die Methoden getPublicKey(), getPublicKeyAlgorithm(), getAuthenticatorData() und getTransports() fehlen in älteren Browsern (z. B. Firefox < 119, Safari < 16) – per Feature-Detection (?.()) absichern.
  • Mit attestation: "none" (Standard) wird die Attestierungsaussage vom Browser anonymisiert; "direct" oder "enterprise" ist nur nötig, wenn die Herkunft des Authentifikators wirklich geprüft werden soll, und kann eine zusätzliche Nutzerabfrage auslösen.