npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

webauthn-p256

v0.0.10

Published

P256 signature utilities for WebAuthn

Downloads

1,309,840

Readme

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

| Name | Description | Type | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | | name | Name for the credential. | string | | attestation | Attestation type for the credential. | 'none' | | authenticatorSelection | An object whose properties are criteria used to filter out the potential authenticators for the credential creation operation. | AuthenticatorSelection | | challenge | Custom creation challenge for the credential. | BufferSource | | createFn | Credential 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> | | excludeCredentialIds | List of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists. | string[] | | rp | An object describing the relying party that requested the credential creation. | { id: string; name: string } | | timeout | Timeout for the credential creation. | number | | user | An object describing the user account for which the credential is generated. | { displayName: string; id: string; name: string } | | returns | P256 Credential | P256Credential |

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

| Name | Description | Type | | -------------- | --------------------------------- | -------------------------------------------------------------------- | | credentialId | Credential ID to use for signing. | string | | getFn | Credential retrieval function. | (options: CredentialRequestOptions) => Promise<Credential \| null> | | hash | Hash to sign. | 0x${string} | | rpId | Relying party identifier. | string | | returns | Signature + 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

| Name | Description | Type | | ----------- | ------------------------------ | ------------------- | | hash | Hash to verify. | 0x${string} | | publicKey | P256 Credential public key. | Hex | | signature | P256 Signature. | Hex | | webauthn | WebAuthn response. | WebAuthnData | | returns | Signature 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

| Name | Description | Type | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | name | Name for the credential. | string | | challenge | Custom creation challenge for the credential. | BufferSource | | excludeCredentialIds | List of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists. | string[] | | rp | An object describing the relying party that requested the credential creation. | { id: string; name: string } | | timeout | Timeout for the credential creation. | number | | user | An object describing the user account for which the credential is generated. | { displayName: string; id: string; name: string } | | returns | Public key credential | PublicKeyCredential |

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

| Name | Description | Type | | -------------- | --------------------------------- | ------------- | | credentialId | Credential ID to use for signing. | string | | hash | Hash to sign. | 0x${string} | | rpId | Relying party identifier. | string | | returns | Credential | Credential |

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

| Name | Description | Type | | ----------- | -------------------------------------- | ------------- | | publicKey | Serialized P256 Credential public key. | 0x${string} | | returns | Parsed 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

| Name | Description | Type | | ----------- | -------------------------------------- | ------------- | | signature | Serialized P256 signature. | 0x${string} | | returns | Parsed 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

| Name | Description | Type | | ----------- | --------------------------- | ----------- | | publicKey | P256 Credential public key. | PublicKey | | returns | Serialized 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

| Name | Description | Type | | ----------- | --------------------------- | ----------- | | signature | P256 signature. | Signature | | returns | Serialized signature. | string |

Authors

License

MIT License