WebAuthn- und Passkey-Inspektor
Füge ein, was dir navigator.credentials.create() oder .get() geliefert hat – das ganze JSON oder ein einzelnes base64url-Feld. Jeder Teil wird dekodiert und erklärt: clientDataJSON, die Flags der Authenticator-Daten Bit für Bit, AAGUID, Credential-ID, der öffentliche Schlüssel im COSE-Format und das Attestierungs-Statement. Bei Anmeldungen wird die ECDSA-P-256-Signatur direkt hier geprüft.
100 % lokal – alles läuft in deinem Browser, nichts wird an einen Server gesendet
Die Antwort von navigator.credentials.create() – ein neuer Passkey.
Dekodiert
Noch nichts eingefügt
alles wird lokal dekodiertFühre in der Konsole deines Browsers eine Registrierung oder eine Anmeldung aus und kopiere das Ergebnis. In Chrome und Safari liefert dir credential.toJSON() genau das JSON, das dieses Feld erwartet; ältere Codepfade brauchen die base64url-Werte aus credential.response. Oder klicke auf Beispiel laden, um eine echte Passkey-Antwort mit gültiger Signatur zu sehen.
How it works
A passkey is an ECDSA key pair — almost always on the P-256 curve — created by your phone, laptop or security key. The private half never leaves that device. Registration hands your server the public half; every later login is a signature made with the private half over data your server chose. There is no shared secret to steal, and the browser refuses to sign for a site the credential was not created on, which is what makes passkeys phishing-resistant.
The browser returns two or three base64url blobs. clientDataJSON is plain JSON describing what the browser saw: the ceremony type, your challenge, and the real origin. authenticatorData is a packed binary record: 32 bytes of SHA-256(RP ID), one flags byte, a 4-byte counter, and — during registration — the AAGUID, the credential ID and the new public key as a CBOR-encoded COSE_Key. During registration that record is wrapped in an attestationObject, a CBOR map that adds the authenticator's optional statement about its own make and model.
Verifying a login is one line of maths: verify(signature, SHA-256(authenticatorData ‖ SHA-256(clientDataJSON)), publicKey). Note what is not in there — the challenge and the origin are only covered because they sit inside clientDataJSON, so a valid signature is necessary but never sufficient: your server still has to read those fields and compare them with what it expects. WebAuthn signatures are ASN.1 DER, not the raw r‖s format JWTs use, which is a common source of "valid signature that will not verify".
The same page checks the attestation statement of a registration in every format the WebAuthn registry defines — packed, tpm, android-key, android-safetynet, fido-u2f, apple, none and compound — and assertion signatures with every COSE algorithm a credential may carry: ES256, ES384, ES512, EdDSA, RS256, PS256 and their relatives. A valid attestation proves that whoever holds the attestation key signed this registration; whether that key belongs to hardware you trust is a separate decision, made by chaining its certificates to a root you accept — normally one the FIDO Metadata Service publishes, which the AAGUID Lookup reads for you.
This page does all of it in your browser: the CBOR decoder and the WebAuthn parsers are written from scratch, ECDSA and EdDSA signatures are checked with the audited @noble/curves library, and RSA signatures with a few dozen lines of RFC 8017 arithmetic. Nothing you paste is uploaded, logged or stored — which matters, because a real response identifies a real credential of a real user.