WebAuthn Compliance
The extension implements the W3C WebAuthn Level 2 specification and the FIDO2 Client-to-Authenticator Protocol (CTAP2).
Implemented ceremonies
- Registration (attestation)
- The full attestation verification ceremony. Supported formats:
none, packed, FIDO-U2F, Apple, TPM, and Android SafetyNet.
The extension uses
web-v5.x for all cryptographic verification.auth/ webauthn- lib - Authentication (assertion)
- Full assertion verification including signature counter checks for authenticator clone detection.
Relying Party configuration
- rpId: Domain-only (no scheme/port). Per-site configurable.
- Origin: Full URL including scheme. Verified against registered origins during ceremonies.
- User verification: Configurable (
required/preferred/discouraged). Defaults torequired.
Challenge handling
Challenges are generated as 32-byte cryptographically random values
(random_), then wrapped in an HMAC-SHA256 signed token:
challengeToken = base64url(nonce || HMAC-SHA256(encryptionKey, nonce || challenge || timestamp))
The token includes:
- A nonce (replay protection -- each token can be used once)
- A timestamp (challenge TTL enforcement)
- HMAC signature (tampering detection)
The plaintext challenge is sent to the browser; the HMAC-signed token is included in the eID response and must be returned verbatim during verification.
Credential storage
Frontend credentials are stored in tx_:
credential_-- WebAuthn credential ID (binary, indexed)id public_-- COSE-encoded public key (binary blob)key_ cose sign_-- Usage counter for clone detectioncount user_-- SHA-256(uid || encryptionKey) -- not the UID itselfhandle aaguid-- Authenticator AAGUID for device identificationtransports-- JSON transport hints
The user_ is a one-way hash to prevent user enumeration
from credential lookups.
Recovery codes
Recovery codes are stored as bcrypt hashes (cost factor 12). Plain text is generated server-side, displayed once to the user, then immediately discarded. The bcrypt hash is stored. On verification, the submitted code is compared against the hash in constant time.
See ADR-010 for the design decision.