clientDataJSON decoder for WebAuthn
Decode the base64url-encoded clientDataJSON sent in WebAuthn registration and assertion ceremonies. Surfaces type, challenge, origin, crossOrigin, and computes the SHA-256 the authenticator signs over.
How to use this tool
What it does
Decodes WebAuthn clientDataJSON — the type, challenge and origin the browser signed over.
When to use it
Use it to confirm a ceremony's challenge and origin match what your server issued.
Worked example
Decode a clientDataJSON to check its origin and that the challenge matches.
Input
Decoded
About clientDataJSON
clientDataJSON is generated by the browser at the moment of navigator.credentials.create() or .get(). It binds the challenge, origin, and ceremony type into a JSON blob; the SHA-256 of the raw bytes is what the authenticator signs over (along with authenticatorData). Origin verification on the RP is the load-bearing anti-phishing primitive in WebAuthn.
Spec
WebAuthn Level 2 §5.8.
Companion
RP ID validator · Challenge viewer · base64url · authenticatorData parser
Frequently asked questions
What is clientDataJSON?
The browser's record of the ceremony: the type, the challenge it was given, the origin it ran on, and a crossOrigin flag. The authenticator signs a SHA-256 hash of these exact bytes.
Why does the SHA-256 hash matter?
Because that hash — not the JSON — is what goes into the signed data. A relying party must hash the bytes it received rather than re-serialising the parsed object, since any whitespace difference changes the hash.
What should the type field contain?
webauthn.create for registration and webauthn.get for authentication. A mismatch between the expected ceremony and this field is a signal the response has been replayed from a different flow.
Why is checking origin so important?
It is the anti-phishing property. The browser writes the true origin, so a relying party that verifies it will reject an assertion produced on a look-alike domain even if the user was fully deceived.
Does anything I paste leave my browser?
Nothing. The tool is entirely client-side: the page ships a static script, does no network calls, and never transmits what you paste. You can confirm it by opening the network tab, or by loading the page and then going offline.