Passkey is a form of authentication used in place of passwords, implemented on the Aptos blockchain through the WebAuthn authenticator. It is designed to provide a more secure and faster way to authenticate users, as well as protect against phishing attacks. Users can create a new site-specific public key credentials on their device and access them with an authorized gesture such as Face ID or Touch ID. At the time of a transaction, users can use Passkey instead of a password to generate a digital signature to verify their identity.
This AIP will benefit developers and users by providing them with an easy way to create non-phishing, recoverable private keys. The impact is as follows:
User-friendliness:
1, WebAuthn Credential registration (private key creation) and transaction signing can be done simply through user authentication (such as device biometrics)
2. Enable users to interact with DApps through their passkey accounts without having to install a mobile or extended wallet: i.e., the headless wallet experience
3. By storing the private key securely in the WebAuthn authenticator rather than in the browser (e.g., local storage), the pass key eliminates the need to set up the wallet password traditionally required to encrypt the private key in the browser
4. On some operating systems, pass keys are backed up and synchronized seamlessly with multiple devices (see Backup Eligibility)
Security:
1, in the pass key, the private key will not be saved in the browser's storage space (for example: localStorage), malicious parties may access it through physical access to the device or through maliciously dependent supply chain attacks
2, by default, the pass key provides a consent-based signature experience and prompts the user to authenticate each time they sign, similar to Apple Pay or Google Pay
3. The pass key is bound to a relying party (e.g., a website like Web Wallet) and is not susceptible to phishing attacks.
Normative detailsPassport uses the WebAuthn specification, created by the FIDO Alliance and the World Wide Web Consortium (W3C), for passport registration and authentication. In the following, this AIP discusses how the WebAuthn specification is used for transaction authentication on Aptos.
(i) Terminology
- **Keyless Accounts: **The security and activity of a keyless account is supported by the OIDC account (e.g., Google account), not by the key.
- Relying Party: ** The website, application, or service that a user is trying to access and is responsible for verifying the signature of the user's access key to ensure that the user is who they claim to be. For simplicity, we can say that "relying party" is synonymous with wallet in this context, as both are responsible for managing the user's access to the private key.
- WebAuthn Authenticator: A cryptographic entity present in hardware or software that can register a user for a given relying party and later assert possession of the registered public key credentials and optionally authenticate the user to the relying party.
- Account Validator: Authorizes the execution of a transaction on Aptos through the aggregated authorization of the sender or approver of the account in the transaction.
(ii) Creating an Aptos account with a passport
During the registration of new WebAuthn credentials, a pair of asymmetric keys (i.e., the private key and its associated public key) is securely generated through the WebAuthn authenticator on that device. The public key associated with the WebAuthn credentials can be used to derive the accounts associated in the chain. The private key of the control account will be protected by the WebAuthn authenticator on the device.
The registration process is particularly important for several reasons:
- The public key associated with the credential is only made public during registration. Assertion responses (signed with a pass key) do not return the public key. Therefore, the registration response must be parsed and the relevant information associated with the credentials should be stored appropriately and persisted on the backend by the wallet.
- The registration response includes flags describing the credential backup characteristics. if pass key backup is an important consideration, these flags should be evaluated before creating an on-chain account.
2.1 PublicKeyCredentialCreationOptions
Each WebAuthn credential is created by the wallet using a set of options called PublicKeyCredentialCreationOptions.These options help to configure many aspects of WebAuthn credentials, including but not limited to:
- Asymmetric key type for credentials (Ed25519, ECDSA, RSA, etc.)
- User authentication requirements during assertion
- Whether WebAuthn credentials should be bound to a single device or be available on multiple platforms.
It is important to carefully consider which options to choose, as they have a significant impact on the pass user experience and cannot be reconfigured after the credential is created.
The following highlights some of the fields in PublicKeyCredentialCreationOptions.
Each WebAuthn credential is created by the wallet using a set of options called PublicKeyCredentialCreationOptions.These options help to configure many aspects of WebAuthn credentials, including but not limited to:
- Asymmetric key type for credentials (Ed25519, ECDSA, RSA, etc.)
- User authentication requirements during assertion
- Whether WebAuthn credentials should be bound to a device or available across platforms.
It is important to carefully consider which options to choose as they have a significant impact on the pass key user experience and cannot be reconfigured after credentials are created.
In PublicKeyCredentialCreationOptions, the following fields are highlighted.
PublicKeyCredentialParameters
For WebAuthn credentials to be compatible with Aptos, the pubKeyCredParams array should contain only supported signature schemes. Currently only secp256r1 is supported, so the array must have an element with alg: -7 to indicate that secp256r1 is the credential type of choice.
PublicKeyCredentialUserEntity
Each authenticator stores a credential mapping from (rpId, userHandle) to a public key credential source. To provide context, the user handle is a unique identifier for the credential, similar to credentialId, but chosen by the wallet rather than the WebAuthn authenticator. If a user creates another credential on the same authenticator (on the same user's device/platform) using the same userHandle as the existing credential, it will overwrite the existing credential and thus the private key associated with the pass account. To avoid this, the wallet must maintain a list of registered credentials and their corresponding user handles.
2.2 Registration response
Upon successful registration of credentials, the authenticator will return a PublicKeyCredential, which will contain a response field of type AuthenticatorAttestationResponse, which will contain most of the information used to authenticate the registration response.
Fully decoding the response field in PublicKeyCredential will result in an AuthenticatorAttestationResponse. the following is an example of its Rust representation:
code reference
pub struct AuthenticatorAttestationResponse {
/// This attribute contains the JSON serialization of the `CollectedClientData` passed by the client to the authenticator to generate this credential. The exact JSON serialization must be preserved because a hash has been calculated on the serialized client data.
#[serde(rename = "clientDataJSON")]
pub client_data_json: Bytes,
/// This is the validator data contained in the authentication object.
pub authenticator_data: Bytes,
/// This is the DER [SubjectPublicKeyInfo] for the new credentials. None if not available.
///
/// [SubjectPublicKeyInfo]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.7
#[serde(skip_serializing_if = "Option::is_none")]
pub public_key: Option,
/// This is the [CoseAlgorithmIdentifier] for the new credentials.
///
/// [CoseAlgorithmIdentifier]: https://w3c.github.io/webauthn/#typedefdef-cosealgorithmidentifier
#[typeshare(serialized_as = "I54")] // because i64 fails for js
pub public_key_algorithm: i64,
/// This attribute contains an authentication object that is opaque to the client and is cryptographically protected to prevent client tampering. The authentication object contains [`AuthenticatorData`] and an authentication statement. The former contains [`Aaguid`], a unique credential ID and [`AttestedCredentialData`] for the credential public key. The content of the authentication statement is determined by the authentication statement format used by the authenticator. It also contains any additional information required by the relying party server to validate the authentication statement, as well as decoding and validating the [`AuthenticatorData`] and JSON-compatible serialization of the client data.
pub attestation_object: Bytes,
/// This field contains a sequence of zero or more unique [`AuthenticatorTransport`] values in dictionary order. These values are the transport methods that the authenticator (is assumed to) support, or an empty sequence if the information is not available. These values SHOULD be members of the [`AuthenticatorTransport`], but the relying party SHOULD accept and store unknown values.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub transports: Option<Vec>,
}
2.3 Authenticator Data
The authenticatorData in the AuthenticatorAttestationResponse contains flags that provide information about the backup eligibility and backup status of the WebAuthn credentials. If the wallet believes that WebAuthn credentials should need to be backed up, the wallet should check the Backup Eligibility (BE) and Backup State (BS) flags in the AuthenticationResponse to ensure that the credentials have been backed up. If both BE and BS are set to true, it means that the credential is a multi-device credential and is currently backed up.
For those wishing to use passkeys as a recoverable private key replacement for their Aptos account, it is highly recommended that both the BE and BS flags be set to true before creating an on-chain account to ensure that the account is recoverable in the event of device loss.
AttestedCredentialData contains the key, which is the public key associated with the WebAuthn credentials.
code reference
pub struct AttestedCredentialData {
/// The AAGUID of the authenticator.
pub aaguid: Aaguid.
/// The credential ID, the length of which is prepended to the byte array. This is not public, as it should not be modified to be longer than u16.
credential_id: Vec,
/// A credential public key in COSE_Key format encoded using the CTAP2-specified CBOR encoding format, as defined in Section 7 of [RFC9052].
/// The COSE_Key encoded credential public key must contain the "alg" parameter and must not contain any other optional parameters.
/// The "alg" parameter must contain a [coset::iana::Algorithm] value.
/// The encoded credential public key MUST also contain any other required parameters specified in the relevant key type specification, i.e., "kty" and algorithm "alg" (see Section 2 of [RFC9053]).
///
/// [RFC9052]: https://www.rfc-editor.org/rfc/rfc9052
/// [RFC9053]: https://www.rfc-editor.org/rfc/rfc9053
pub key: CoseKey,
}
The credential public key is stored in CBOR Object Signing and Encryption format (COSE). the CoseKey includes the x and y coordinates of the public key, which are combined to form the public key.
With the original public key, the Aptos account address can be derived. Note that the default authentication key derivation method will be different depending on the type of account created (SingleKey or MultiKey).
(iii) Signing transactions
In traditional implementations of the client-server WebAuthn specification, both registration of new credentials and authentication assertions use challenge-response authentication to avoid many types of attacks. Randomized challenges are particularly important for protection against replay attacks (§13.4.3).
Aptos is adapting the WebAuthn specification for on-chain accounts and transactions. As many of you already know, on-chain transactions include a sequence number to avoid on Aptos. As a result, if a transaction is used as a challenge to a WebAuthn assertion, the risk of replay attacks is mitigated even if the challenge is not randomly generated by the wallet.
In traditional implementations of the client-server WebAuthn specification, both registration of new credentials and authentication assertions use challenge-response authentication to avoid many types of attacks. Randomized challenges (challenges) are particularly important to prevent replay attacks (§13.4.3).
Aptos is integrating the WebAuthn specification into on-chain account and transaction validation. Typically, on-chain transactions include a sequence number to prevent replay attacks on the Aptos network. This makes validation challenges that use transactions as WebAuthn assertions more secure and less susceptible to replay attacks, even if the challenge is not randomly generated by the wallet.
3.1 challenge code reference
dictionary PublicKeyCredentialRequestOptions {
required BufferSource challenge.
unsigned long timeout.
USVString rpId.
sequence allowCredentials = [];
DOMString userVerification = "preferred";
sequence hints = [];
DOMString attestation = "none";
sequence attestationFormats = [];
AuthenticationExtensionsClientInputs extensions.
};
During assertion, the SHA3-256 digest of signing_message(raw_transaction) is provided as a challenge in PublicKeyCredentialRequestOptions. before computing the SHA3-256 of raw_transaction, the signing_message function is applied to achieve domain separation without further increasing the size of the challenge.
In other words, CHALLENGE is:
challenge = H({signing\_message(raw\_transaction)})
where is the SHA3-256 hash.
3.2 AuthenticatorAssertionResponse
After successfully submitting the PublicKeyCredentialRequestOptions via navigator.credentials.get(), the AuthenticatorAssertionResponse is returned to the client, as shown below:
code block
interface AuthenticatorAssertionResponse : AuthenticatorResponse {
[SameObject] readonly attribute ArrayBuffer authenticatorData.
[SameObject] readonly attribute ArrayBuffer signature.
[SameObject] readonly attribute ArrayBuffer? userHandle;
[SameObject] readonly attribute ArrayBuffer?attestationObject;
};
3.3 Signature
The signature in the AuthenticatorAssertionResponse is computed on the message m, where m is a binary concatenation of the SHA-256 hashes of authenticatorData and clientDataJSON .1. clientDataJSON is a CollectedClientData's JSON serialization of the challenge and other data about the request, such as the origin and type of the request.
where H is the SHA-256 hash (note: not SHA3-256), is the passkey private key, and $||$ is the binary link.
3.4 AuthenticatorAssertionResponse
interface AuthenticatorAssertionResponse : AuthenticatorResponse {
[SameObject] readonly attribute ArrayBuffer authenticatorData.
[SameObject] readonly attribute ArrayBuffer signature.
[SameObject] readonly attribute ArrayBuffer? userHandle;
};
(iv) Transaction submission
This AIP is based on the new TransactionAuthenticator and AccountAuthenticator constructs proposed in AIP-55, and uses SingleKeyAuthenticator and MultiKeyAuthenticator, which support single-key and k-of-n MultiKeyAuthenticator. A new WebAuthn variant has been added under AnySignature and a new Secp256r1Ecdsa variant has been added under AnyPublicKey, allowing users to submit transactions from SingleKey or MultiKey accounts using Secp256r1 WebAuthn credentials.
AccountAuthenticator::SingleKey { authenticator: SingleKeyAuthenticator }
AccountAuthenticator::MultiKey { authenticator: MultiKeyAuthenticator }
pub struct SingleKeyAuthenticator {
public_key: AnyPublicKey,
signature: AnySignature,
}
pub struct MultiKeyAuthenticator {
public_keys: MultiKey,
signatures: Vec,
signatures_bitmap: aptos_bitvec::BitVec,
}
pub struct MultiKey {
public_keys: Vec,
signatures_required: u8,
}
pub enum AnySignature {
...,
WebAuthn {
signature: PartialAuthenticatorAssertionResponse,
},
}
pub enum AnyPublicKey {
...,
Secp256r1Ecdsa {
public_key: secp256r1_ecdsa::PublicKey,
},
}
Each signature variant in AnySignature is structured as a PartialAuthenticatorAssertionResponse. the PartialAuthenticatorAssertionResponse contains all of the information needed to validate the WebAuthn signature.
pub enum AssertionSignature {
Secp256r1Ecdsa {
signature: secp256r1_ecdsa::Signature,
},
}
pub struct PartialAuthenticatorAssertionResponse {
/// This attribute contains the original signature returned from the authenticator.
/// Note: Many of the signatures returned from WebAuthn assertions are not original signatures.
/// For example, the secp256r1 signature is encoded as [ASN.1 DER Ecdsa-Sig_value](https://www.w3.org/TR/webauthn-3/#sctn-signature-attestation-types)
/// If the signature is encoded, the client is expected to convert the encoded signature to the original before including it in the transaction.
signature: AssertionSignature.
/// This attribute contains the byte serialization of the authenticator data passed to the authenticator via the client as [`CollectedClientData`](CollectedClientData).
/// The exact JSON serialization must be preserved because a hash has been computed on the serialized client data.
authenticator_data: Vec,
/// This property contains the serialization of the JSON byte of [`CollectedClientData`](CollectedClientData) passed to the authenticator via the client.
/// The exact JSON serialization must be preserved because a hash has been computed on the serialized client data.
client_data_json: Vec,
}
(v) Signature verification
Once the transaction reaches the signature verification step, the WebAuthn authenticator performs the following steps to verify the signature :
- Verify that the actual RawTransaction matches the challenge expected in the clientDataJSON by computing the
where H is the SHA3-256 hash and verifies that it is equal to the challenge in clientDataJSON.
[!tip]
Translator's note: The original formula is H(signing\\\_message(raw\\\transaction))
- Use clientDataJSON and authenticatorData to reconstruct the message m, the
- For message m, public key pk and original signature , apply a verification function to determine if V(σ, m, pk) evaluates to true
Assuming everything else is correct, the validation passes, and the other validators agree with the result, the transaction will be successful and will be added to the blockchain state.
(vi) Transaction submission summaries
To summarize, the high-level protocol for authentication assertions in the Aptos Blockchain implementation of the WebAuthn specification is as follows:
- The client provides a challenge in the form of a SHA3-256 RawTransaction of signing_message. we use the SHA3-256 of the RawTransaction rather than the RawTransaction itself to limit the size of the challenge, which is part of the We use the SHA3-256 of the RawTransaction rather than the RawTransaction itself to limit the size of the challenge, which is part of clientDataJSON.
- If the user agrees, the user agent (browser) will request the WebAuthn authenticator to use Passkey credentials to generate an assertion signature on the message m containing the challenge and return the response to the client.
- The client then sends the SignedTransaction to the blockchain, where the SignedTransaction's signature field contains the relevant fields from the WebAuthn authenticator's response
- The blockchain will verify that the SignedTransaction's signature is valid for the same message m (which contains the RawTransaction) and verify that the asserted signature is valid for the corresponding public key
For more details, please refer to AIP-66 (https://github.com/ALCOVE-LAB/Aptos-Docs/blob/main/AIP/aip-66.md)
We have translated the Chinese version of the official English documentation for your reference.
All of the above content is reproduced from the Internet, does not represent the position of AptosNews, is not investment advice, investment risk, the market need to be cautious, such as infringement, please contact the administrator to delete.