WebAuthn registration creates a public-key credential through the browser and authenticator, then sends the credential data to the relying party for association with a user. The private key remains with the authenticator; the server stores the credential information needed to verify later responses. section 15.3
A basic registration flow proceeds as follows:
- Offer a Register WebAuthn Credential action on a web page. section 15.3
- Check browser support through window.PublicKeyCredential and stop with an error when WebAuthn is unavailable. section 15.3
- Prepare creation options containing a challenge, relying-party name, user identity, public-key algorithm, authenticator preference, timeout, and attestation setting. section 15.3
- Call navigator.credentials.create(), handle a missing credential, and collect the resulting credential data. section 15.3
- Send and associate the registration details, including the credential ID and returned attestation or client data, with the account. section 15.3 section 15.3.1
A local passkey registration
Serve the page from localhost with the JDK jwebserver command, click Register WebAuthn Credential, and confirm the platform-authentication prompt. The browser then produces an attestation object and client data that can be displayed as Base64-encoded output and sent to a Java backend. section 15.3
Listing 15.4 Requesting creation of the public key
async function registerWebAuthn() {
if (!window.PublicKeyCredential) {
console.error("WebAuthn is not supported in this browser.");
return;
}
const publicKeyCredentialCreationOptions = {
challenge: new Uint8Array(32),
rp: { name: "My WebAuthn App" },
user: {
id: new Uint8Array(16),
name: "user@example.com",
displayName: "User Example"
},
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
authenticatorSelection: { authenticatorAttachment: "platform" },
timeout: 60000, // Timeout in milliseconds
attestation: "direct"
};
try {
const credential = await navigator.credentials
.create({ #1
publicKey: publicKeyCredentialCreationOptions
});
if (!credential) { #2
console.error("Credential creation failed.");
return;
}
const attestationObject = #3
btoa(String.fromCharCode(...new
Uint8Array(credential.response.attestationObject)));
const clientDataJSON =
btoa(String.fromCharCode(...new
Uint8Array(credential.response.clientDataJSON)));
const credentialId =
btoa(String.fromCharCode(...new
Uint8Array(credential.rawId)));
console.log("WebAuthn Registration Data:");
console.log("Attestation Object:", attestationObject);
console.log("Client Data JSON:", clientDataJSON);
console.log("Credential ID:", credentialId);
} catch (error) {
console.error("WebAuthn registration failed:", error);
}
}
Inspect the complete browser-side creation call, including the WebAuthn options, null-credential check, and asynchronous navigator.credentials.create() operation. section 15.3
