WebAuthn
Overview
WebAuthn is a web standard for passwordless login, developed by the FIDO Alliance and W3C. This authentication method leverages asymmetric cryptography stored on a user’s personal device. The authentication process involves the user’s device signing a challenge generated by the server, which the server then verifies. The user’s private key is managed by an ‘Authenticator’ within a secure device, which can be either a built-in authenticator (e.g., secure elements in smartphones) or an external authenticator (e.g., USB security keys). Through this process, WebAuthn prevents man-in-the-middle attacks, making user authentication more secure and convenient.
pubKeyCredParams
WebAuthn supports various types of public key cryptography algorithms. These algorithms can be chosen based on security, compatibility, and performance considerations, each offering different characteristics and benefits. The main public key algorithms are:
- -7 (ES256)
- -8 (Ed25519)
- -257 (RS256)
These algorithms are designed to be suitable for different uses and environments, allowing for appropriate selection based on user needs and technical requirements. A WebAuthn implementation supports one or more of these algorithms to meet diverse environments and requirements.
Signing and Verification
Most blockchains serialize transactions in various ways, hash the resulting byte array, and sign it to verify the transaction’s validity. Therefore, with just the signature, transaction, and public key, the validity of a transaction can be verified.
In contrast, WebAuthn requires additional data for signature verification:
Among this data, the challenge attribute of clientDataJSON contains information generated by the server to verify that the request is recent and not reused.
Therefore, to utilize WebAuthn for blockchain signatures, additional data such as clientDataJSON and authenticatorData are needed alongside the signature, transaction, and public key. This necessitates defining a new serialization schema for transactions.
const txHash = sha256(tx);
const { response } = await navigator.credentials.get({
challenge: txHash,
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
...
});
const authenticatorData = new Uint8Array(response.authenticatorData);
const { challenge } =
JSON.parse(Buffer.from(response.clientDataJSON).toString()));
const clientDataHASH = sha256(new Uint8Array(response.clientDataJSON));
const signature = new Uint8Array(response.signature);
const signedData =
new Uint8Array(authenticatorData.length + clientDataHASH.length);
signedData.set(authenticatorData);
signedData.set(clientDataHASH, authenticatorData.length);
const isValidSig =
secp256r1.verify(signature, sha256(signedData), publicKey);
const isValidTx =
Buffer.from(challenge, 'base64').equals(Buffer.from(sha256(message)))
if (isValidSig && isValidTx) {
console.log("Verification success.");
} else {
console.log("Verification failed.");
}
The following proposal outlines the incorporation of WebAuthn into blockchain transaction signing and verification processes, addressing the need for additional data and a new serialization schema. This approach leverages the security and convenience of WebAuthn, aiming to enhance the overall security and user experience in blockchain environments.