Pular para o conteúdo
ecdsa.com

Inspetor de WebAuthn e chaves de acesso (WebAuthn / Passkey Inspector)

Cole o que navigator.credentials.create() ou .get() retornou — o JSON inteiro ou um único campo base64url. Cada parte é decodificada e explicada: clientDataJSON, as flags dos dados do autenticador bit a bit, AAGUID, ID da credencial, a chave pública COSE e a declaração de atestado. Nos logins, a assinatura ECDSA P-256 é verificada aqui mesmo.

100% local — tudo roda no seu navegador, nada é enviado a nenhum servidor

A resposta de navigator.credentials.create() — uma nova chave de acesso.

Decodificado

Nada colado ainda

tudo é decodificado localmente

No console do navegador, execute um registro ou um login e copie o resultado. No Chrome e no Safari, credential.toJSON() retorna exatamente o JSON que esta caixa espera; caminhos de código mais antigos precisam dos valores base64url de credential.response. Ou clique em Carregar exemplo para ver uma resposta real de chave de acesso, com assinatura válida.

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.