2.5 KiB
jwk
Purpose
Round-trip converter between RFC 9052 COSE_Key instances and RFC 7517 JWK
shapes. WebAuthn attestation flows often need to hand a public key to a
WebCrypto-style verifier that consumes JWK; conversely, server-issued
JWK-formatted keys may need to land in a CBOR-encoded COSE structure. The
two conversions preserve every field that has a defined cross-format
mapping.
Features
coseKeyToJwk(key)— accepts anyCoseKeydiscriminant (EC2, OKP, RSA, Symmetric) and emits the matching JWK (EC,OKP,RSA,oct).jwkToCoseKey(jwk)— reverse mapping with full byte-string round-trip.- Byte-string fields use RFC 4648 §5 base64url encoding without padding.
kidis treated as UTF-8 bytes on the COSE side and a string on the JWK side; conversion is lossy only if a non-UTF-8 kid is in play (rare, and RFC 9052 §3.1 documents the convention).alground-trips through a fixed COSE↔JWK label table so the typed algorithm lands consistently on either side.
Usage: Basic Example
import { coseKeyToJwk, jwkToCoseKey } from "@suaveplan/cbor/cose";
const jwk = coseKeyToJwk(coseKey);
const back = jwkToCoseKey(jwk);
Usage: Advanced Example
import { decodeCoseKey, coseKeyToJwk } from "@suaveplan/cbor/cose";
// Attestation key from CTAP2
const cose = decodeCoseKey(attestationKeyBytes);
const jwk = coseKeyToJwk(cose);
// Hand off to WebCrypto
const cryptoKey = await crypto.subtle.importKey(
"jwk",
jwk,
{ name: "ECDSA", namedCurve: "P-256" },
false,
["verify"],
);
API Reference
coseKeyToJwk(key: CoseKey): Jwk— discriminator-aware conversion to JWK.jwkToCoseKey(jwk: Jwk): CoseKey— reverse conversion.Jwk = Ec2Jwk | OkpJwk | RsaJwk | SymmetricJwk(typed union).
Throws CborError(UNEXPECTED_TYPE) for incompatible curves (EC2 with a
non-P curve, OKP with a non-Ed/X curve), unknown JWK alg strings, and
malformed base64url input via the underlying atob.
Implementation Notes
base64url encoding is implemented inline with btoa/atob rather than
pulling in @suaveplan/crypto-utils so this module stays free of crypto
deps. Standard base64 padding (=) is stripped on output and re-padded on
input — the RFC 4648 §5 spec allows omission of padding and major JWK
producers do strip it. RSA JWKs use lowercase param names (dp, dq, qi)
per RFC 7518 §6.3.2; COSE_Key uses the labels from RFC 8230 §4 (-6, -7,
-8). The bridge preserves the field-by-field correspondence.