# CoseToKey()

Converts a COSE key into a usable Java security key. COSE (CBOR Object Signing and Encryption) is the key format used by WebAuthn/passkeys — when a user registers a passkey, the browser sends their public key in COSE format.

Accepts either a struct (e.g. from [CborDecode()](cbordecode.md)) or raw CBOR bytes. Returns a key pair struct with `public` (and `private` if the COSE key includes private material). Supports EC (P-256, P-384, P-521) and Ed25519 keys.

**Requires Extension:** [Crypto Extension](https://download.lucee.org/#17AB52DE-B300-A94B-E058FC978BE4542D)

```
CoseToKey( coseKey=any );
```

**Returns:** struct

# Arguments

| Argument | Type | Required | Description | Default |
|----------|------|----------|-------------|---------|
| coseKey | any | Yes | COSE key as a struct (from CborDecode) or raw CBOR-encoded binary |  |

# Usage Notes

**COSE key format:** COSE keys use integer keys to identify fields (defined in RFC 9052):

- `1` = key type (2 for EC, 1 for OKP/EdDSA)
- `3` = algorithm (-7 for ES256, -35 for ES384, -36 for ES512, -8 for EdDSA)
- `-1` = curve (1 for P-256, 2 for P-384, 3 for P-521, 6 for Ed25519)
- `-2` = x coordinate (binary)
- `-3` = y coordinate (binary, EC only)
- `-4` = private key (binary, only if private material is present)

You don't need to construct these structs yourself — they come from [CborDecode()](cbordecode.md) when decoding WebAuthn authenticator data, or from [KeyToCose()](keytocose.md) when converting existing keys.

**Return value:** Always returns a struct with a `public` key. If the COSE key contains private material (key `-4`), the struct also includes a `private` key.

**WebAuthn:** The vast majority of passkeys use EC P-256 (ES256), but Ed25519 support is growing. P-384 and P-521 are rare in practice but supported.

# Examples

```cfml
// Roundtrip: generate a key pair, convert to COSE and back
keyPair = GenerateKeyPair( "P-256" );
cose = KeyToCose( keyPair );
keys = CoseToKey( cose );

// The roundtripped key works for signature verification
sig = GenerateSignature( "test data", keyPair.private );
isValid = VerifySignature( "test data", sig, keys.public ); // true

// CoseToKey also accepts raw CBOR bytes — it decodes them internally
cborBytes = CborEncode( cose );
keys = CoseToKey( cborBytes );
// Same result as CoseToKey( CborDecode( cborBytes ) )

// Ed25519 keys work too
edKp = GenerateKeyPair( "Ed25519" );
edCose = KeyToCose( edKp );
edKeys = CoseToKey( edCose );
sig = GenerateSignature( "test data", edKp.private );
isValid = VerifySignature( "test data", sig, edKeys.public ); // true

// WebAuthn registration: extract the public key from authenticator data
attestationObject = CborDecode( Base64UrlDecode( response.attestationObject ) );
authData = attestationObject.authData;
// Parse authData to extract the COSE key bytes (after rpIdHash, flags, counter, credId)
coseKeyStruct = CborDecode( coseKeyBytes );
keys = CoseToKey( coseKeyStruct );
publicKey = keys.public;
// Store KeyToPem( publicKey ) alongside the credential ID

// WebAuthn authentication: verify a passkey signature
isValid = VerifySignature(
	data = signedData,
	signature = Base64UrlDecode( response.signature ),
	publicKey = storedPublicKeyPem,
	algorithm = "SHA256withECDSA"
);
```







# Categories

[Cryptography](../../categories/crypto.md)

# See Also

[CborDecode()](cbordecode.md), [GenerateKeyPair()](generatekeypair.md), [KeyToCose()](keytocose.md), [VerifySignature()](verifysignature.md)