跳到主要内容
ecdsa.com

通行密钥沙盒

用你的手机、笔记本电脑或安全密钥注册通行密钥,然后用它登录。依赖方在本页面中运行,并展示服务器执行的每个步骤;不会向任何地方发送数据。

100% 本地运行——所有操作都在你的浏览器中完成,不会向任何服务器发送数据

当前浏览器

RP ID
—
源
—
依赖方设置
由认证器显示;不会离开本页面
提供的算法(pubKeyCredParams)
PEM 证书,例如来自 FIDO 元数据服务,用于评估证明证书链
在此注册的凭证

还没有凭证:请先注册一个。

重放规范中的流程

用 WebAuthn 规范中的测试向量运行依赖方——其中的注册和登录由真实的证明格式生成——无需认证器。

来源:W3C Web Authentication Level 3 第 16 节“测试向量”(使用源 https://example.org 与 RP ID example.org),以及其中的证明 CA。核对日期:2026年10月20日。

A relying party in your browser tab

A passkey is a WebAuthn credential: a key pair created by an authenticator — the secure hardware of your phone or laptop, a password manager, a USB security key — for exactly one website, its relying party. The private key never leaves the authenticator; the site stores only the public key and later checks signatures made with it. Because every signature covers the origin the browser actually talked to, a passkey cannot be phished.

Normally the relying party is a server. In this sandbox it is the page itself: it plays the server's role with the same code a server would run — options generation and the verification procedures of WebAuthn Level 3 §7.1 and §7.2 — so you can watch both sides of a ceremony with your own authenticator. The RP ID is this site's host name, which is why the passkeys you create here appear in your password manager as passkeys for this site.

Registration, step by step

Pressing Register a passkey generates PublicKeyCredentialCreationOptions exactly as a server would send them in JSON: the relying party, a user with a random 32-byte handle (never anything that identifies the person, §14.6.1), a fresh 32-byte challenge, the algorithms you allow, the credentials already registered in excludeCredentials, and your choices for residentKey, userVerification, attestation, attachment and hints. The browser turns them into the binary form with PublicKeyCredential.parseCreationOptionsFromJSON (the sandbox converts them itself where the browser lacks it), calls navigator.credentials.create(), and the response comes back through credential.toJSON(). Then the sandbox verifies, in the specification's order:

  • clientDataJSON — type is webauthn.create, the challenge is the one just issued, the origin is this page's origin, and crossOrigin and topOrigin are as expected;
  • authenticator data — rpIdHash is SHA-256 of the RP ID; the flags: user present (UP), user verified (UV), backup eligible (BE) and backed up (BS), which tell a synced passkey from a device-bound one;
  • the credential — its ID, length and uniqueness, its COSE public key and algorithm against the ones offered, and the credProps extension that says whether it is discoverable;
  • the attestation statement — none, packed, tpm, android-key, android-safetynet, fido-u2f, apple or compound, each verified as §8 prescribes, and, if you paste roots from the FIDO Metadata Service, the certificate chain behind it.

If everything passes, the sandbox stores the credential record a server would keep — ID, public key, algorithm, signature counter, flags, transports, AAGUID — and shows it.

Sign-in, step by step

Sign in with a passkey sends PublicKeyCredentialRequestOptions with a new challenge — with an empty allow list, so that the authenticator offers the passkeys it holds for this site (discoverable sign-in, the passkey way), or with the credentials registered here. The assertion is checked against the stored record: the credential and its user handle, the client data (webauthn.get), the RP ID hash and flags, a backup-eligibility flag that must not change, the signature over authenticatorData ‖ SHA-256(clientDataJSON) with the stored public key, and the signature counter, which must increase unless the authenticator does not keep one (synced passkeys report 0). The updated record is shown and kept.

When a ceremony fails in the browser, the sandbox explains the DOMException: NotAllowedError for a cancelled or timed-out prompt or no matching credential, InvalidStateError when the authenticator already holds a credential in excludeCredentials, SecurityError for an RP ID the origin may not use.

Without an authenticator at hand, Replay a specification ceremony runs the same verification on the test vectors of WebAuthn Level 3 §16 — registrations with no attestation and with packed, TPM, Android Key, Apple and FIDO U2F attestation, each followed by a sign-in. To decode a response captured elsewhere, use the WebAuthn inspector; for the server side in your own stack, read Passkeys for developers: WebAuthn without the guesswork.