0.0.10 • Published 11 months ago

webauthn-p256 v0.0.10

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Table of Contents

Install

npm i webauthn-p256
pnpm i webauthn-p256
bun i webauthn-p256

Usage

import { createCredential, sign, verify } from 'webauthn-p256'

// Register a WebAuthn credential (ie. passkey).
const credential = createCredential({
  name: 'Example',
})

// Sign hash with credential.
const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash: '0x...'
})

// Verify signature with hash, public key, and WebAuthn data.
const verified = await verify({
  hash: '0x...',
  publicKey: credential.publicKey,
  signature,
  webauthn,
})

Onchain Verification

We can also verify WebAuthn signatures onchain via contracts that expose a WebAuthn verifier interface.

The example below uses Viem to call the verify function on the WebAuthn.sol contract. However, in a real world scenario, a contract implementing the WebAuthn verifier interface will call the verify function (e.g. a isValidSignature interface on an ERC-4337 Smart Wallet).

Note: Bytecode for the code variable can be obtained here.

import { createCredential, parsePublicKey, parseSignature, sign } from 'webauthn-p256'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const abi = parseAbi([
  'struct WebAuthnAuth { bytes authenticatorData; string clientDataJSON; uint256 challengeIndex; uint256 typeIndex; uint256 r; uint256 s; }',
  'function verify(bytes, bool, WebAuthnAuth, uint256, uint256)'
])
const code = '0x...'

const credential = createCredential({
  name: 'Example',
})

const hash = '0x...'

const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash
})

const { x, y } = parsePublicKey(credential.publicKey)
const { r, s } = parseSignature(signature)

const verified = await client.readContract({
  abi,
  code,
  functionName: 'verify',
  args: [
    hash,
    webauthn.userVerificationRequired,
    { ...webauthn, r, s },
    x,
    y,
  ],
})

Core Reference

createCredential

Creates a P256 WebAuthn credential with a Passkey authenticator.

Usage

import { createCredential } from 'webauthn-p256'

const credential = createCredential({
  name: 'Example',
})

API

NameDescriptionType
nameName for the credential.string
attestationAttestation type for the credential.'none'
authenticatorSelectionAn object whose properties are criteria used to filter out the potential authenticators for the credential creation operation.AuthenticatorSelection
challengeCustom creation challenge for the credential.BufferSource
createFnCredential creation function. Useful for environments that do not support the WebAuthn API natively (i.e. React Native or testing environments).(options: CredentialCreationOptions) => Promise<Credential \| null>
excludeCredentialIdsList of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists.string[]
rpAn object describing the relying party that requested the credential creation.{ id: string; name: string }
timeoutTimeout for the credential creation.number
userAn object describing the user account for which the credential is generated.{ displayName: string; id: string; name: string }
returnsP256 CredentialP256Credential

sign

Signs a hash using a stored credential. If no credential is provided, a prompt will be displayed for the user to select an existing credential that was previously registered.

Usage

import { sign } from 'webauthn-p256'

const credential = { /* ... */ }

const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash: '0x...',
})

API

NameDescriptionType
credentialIdCredential ID to use for signing.string
getFnCredential retrieval function.(options: CredentialRequestOptions) => Promise<Credential \| null>
hashHash to sign.0x${string}
rpIdRelying party identifier.string
returnsSignature + WebAuthn response.{ signature: Hex; webauthn: WebAuthnData }

verify

Verifies a signature using the credential public key and the hash which was signed.

!WARNING The verify implementation mimics Daimo's audited WebAuthn.sol – however, this TypeScript implementation is unaudited.

Usage

import { verify } from 'webauthn-p256'

const credential = { /* ... */ }
const signature = '0x...'
const webauthn = { /* ... */ }
 
const valid = await verify({ 
  hash: '0x...', 
  publicKey: credential.publicKey, 
  signature,
  webauthn,
})

API

NameDescriptionType
hashHash to verify.0x${string}
publicKeyP256 Credential public key.Hex
signatureP256 Signature.Hex
webauthnWebAuthn response.WebAuthnData
returnsSignature verification result.boolean

Utilities Reference

getCredentialCreationOptions

Returns the credential creation options for a P256-flavoured WebAuthn credential.

Usage

import { getCredentialCreationOptions } from 'webauthn-p256'

const options = getCredentialCreationOptions({
  name: 'Example',
})

API

NameDescriptionType
nameName for the credential.string
challengeCustom creation challenge for the credential.BufferSource
excludeCredentialIdsList of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists.string[]
rpAn object describing the relying party that requested the credential creation.{ id: string; name: string }
timeoutTimeout for the credential creation.number
userAn object describing the user account for which the credential is generated.{ displayName: string; id: string; name: string }
returnsPublic key credentialPublicKeyCredential

getCredentialSignRequestOptions

Returns the credential sign request options for a P256-flavoured WebAuthn credential.

Usage

import { getCredentialSignRequestOptions } from 'webauthn-p256'

const options = getCredentialSignRequestOptions({
  credentialId: '...',
  hash: '0x...',
})

API

NameDescriptionType
credentialIdCredential ID to use for signing.string
hashHash to sign.0x${string}
rpIdRelying party identifier.string
returnsCredentialCredential

parsePublicKey

Parses a serialized public key into x and y coordinates.

Usage

import { parsePublicKey } from 'webauthn-p256'

const publicKey = parsePublicKey('0x...')

console.log(publicKey)
// { x: 1231..., y: 12412... }

API

NameDescriptionType
publicKeySerialized P256 Credential public key.0x${string}
returnsParsed public key.PublicKey

parseSignature

Parses a serialized signature into r and s coordinates.

Usage

import { parseSignature } from 'webauthn-p256'

const signature = parseSignature('0x...')

console.log(signature)
// { r: 1231..., s: 12412... }

API

NameDescriptionType
signatureSerialized P256 signature.0x${string}
returnsParsed P256 signature.Signature

serializePublicKey

Serializes a public key into a hex string or bytes.

Usage

import { serializePublicKey } from 'webauthn-p256'

const publicKey = serializePublicKey({
  x: 12341...,
  y: 12341...,
})

console.log(publicKey)
// '0x...'

API

NameDescriptionType
publicKeyP256 Credential public key.PublicKey
returnsSerialized public key.string

serializeSignature

Serializes a signature into a hex string or bytes.

Usage

import { serializeSignature } from 'webauthn-p256'

const signature = serializeSignature({
  r: 12341...,
  s: 12341...,
})

console.log(signature)
// '0x...'

API

NameDescriptionType
signatureP256 signature.Signature
returnsSerialized signature.string

Authors

License

MIT License

0.0.10

11 months ago

0.0.9

11 months ago

0.0.8

12 months ago

0.0.7

12 months ago

0.0.6

12 months ago

0.0.5

12 months ago

0.0.4

12 months ago

0.0.3

12 months ago

0.0.2

1 year ago

0.0.1

1 year ago

0.0.0

1 year ago