Signatur
Beschreibung
AuthenticatorResponse ist das gemeinsame Basis-Interface der Antworten, die ein Authenticator (z. B. Passkey-Anbieter, Sicherheitsschlüssel, Windows Hello, Touch ID) im Rahmen von WebAuthn liefert. Es wird nie direkt instanziiert. Stattdessen bekommst du eine der beiden Unterklassen über die Eigenschaft response eines PublicKeyCredential:
AuthenticatorAttestationResponse: Ergebnis vonnavigator.credentials.create()bei der Registrierung eines neuen Schlüsselpaars. Sie enthält dasattestationObjectund den öffentlichen Schlüssel.AuthenticatorAssertionResponse: Ergebnis vonnavigator.credentials.get()bei der Anmeldung. Sie enthältauthenticatorData,signatureunduserHandle.
Das Basis-Interface definiert genau eine Eigenschaft: clientDataJSON, einen ArrayBuffer mit UTF-8-kodiertem JSON. Darin stehen unter anderem type ("webauthn.create" bzw. "webauthn.get"), die Base64URL-kodierte challenge und der origin. Diese Daten signiert bzw. hasht der Authenticator mit. Deshalb muss der Server sie prüfen, damit Replay- und Phishing-Angriffe abgewehrt werden.
In der Praxis leitest du clientDataJSON zusammen mit den übrigen Antwortdaten an deinen Server weiter. Dafür kodierst du die Werte typischerweise als Base64URL. Der Server prüft dann Challenge, Origin und Typ sowie die Signatur bzw. die Attestierung.
Rückgabewert
AuthenticatorAttestationResponse oder AuthenticatorAssertionResponse erhältst du über PublicKeyCredential.response. Einzige Eigenschaft des Basis-Interfaces: clientDataJSON (ArrayBuffer, nur lesbar).Beispiele
Registrierung: AuthenticatorResponse aus credentials.create() erhalten
// Challenge kommt in der Praxis vom Server
const challenge = crypto.getRandomValues(new Uint8Array(32));
const credential = await navigator.credentials.create({
publicKey: {
challenge,
rp: { name: 'programmierung.net' },
user: {
id: new TextEncoder().encode('user-42'),
name: 'max@example.org',
displayName: 'Max Muster'
},
pubKeyCredParams: [{ type: 'public-key', alg: -7 }] // ES256
}
});
const response = credential.response;
console.log(response instanceof AuthenticatorResponse);
console.log(response.constructor.name);
clientDataJSON dekodieren und auswerten
const parseClientData = (response) => {
const json = new TextDecoder().decode(response.clientDataJSON);
return JSON.parse(json);
};
const credential = await navigator.credentials.get({
publicKey: {
challenge: crypto.getRandomValues(new Uint8Array(32)),
userVerification: 'preferred'
}
});
const clientData = parseClientData(credential.response);
console.log(clientData.type, clientData.origin);
Antwort Base64URL-kodiert an den Server senden
const toBase64Url = (buffer) =>
btoa(String.fromCharCode(...new Uint8Array(buffer)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const sendAssertion = async (credential) => {
const r = credential.response; // AuthenticatorAssertionResponse
const payload = {
id: credential.id,
clientDataJSON: toBase64Url(r.clientDataJSON),
authenticatorData: toBase64Url(r.authenticatorData),
signature: toBase64Url(r.signature),
userHandle: r.userHandle ? toBase64Url(r.userHandle) : null
};
const res = await fetch('/webauthn/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
return res.ok;
};
// Wichtig · Fallstricke
- Nicht instanziierbar:
new AuthenticatorResponse()wirft einenTypeError. Das Interface dient nur als gemeinsame Basis und fürinstanceof-Prüfungen. - Nur in sicheren Kontexten: WebAuthn gibt es nur über HTTPS (oder auf
localhost). In Cross-Origin-iframes brauchst du die Berechtigungsrichtliniepublickey-credentials-getbzw.publickey-credentials-create. - Serverseitig prüfen: Verlass dich nie auf eine Prüfung im Client. Der Server muss in
clientDataJSONchallenge,originundtypegegen die erwarteten Werte vergleichen und anschließend die Signatur bzw. die Attestierung verifizieren. Für jede Anfrage erzeugt der Server eine neue Challenge und verwendet sie nur einmal. - Binärdaten:
clientDataJSONist einArrayBuffer, kein String. Für JSON-Transporte kodierst du ihn als Base64URL. Neuere Browser bieten dafürPublicKeyCredential.prototype.toJSON()an; ältere Browser unterstützen das nicht vollständig. - Kompatibilität: Chrome/Edge 67+, Firefox 60+ und Safari 13+ unterstützen WebAuthn. Ältere Browser erkennst du per Feature-Erkennung mit
window.PublicKeyCredential.