doc: COSE -> JWK Mappings
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Documentation
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- javascript
- Domain
- authentication, documentation, security
Research direction
Start by reviewing the COSE/JWK mapping tables and the linked IANA, RFC, Node WebCrypto, and caniuse references. Determine where this repository's documentation presents passkey key types, then document the agreed modern and legacy mappings with browser and Node support. Done means the mappings and compatibility notes are complete and internally consistent.
Written by the indexing model from the issue text.
Description
Note:
- Browser WebCrypto only supports P-256
- Node
node:cryptoand WebCrypto also supports Ed25519 and secp256k1 (as justSHA256) - whatever is supported by openssl v3- https://nodejs.org/docs/latest/api/webcrypto.html#algorithm-matrix
- https://nodejs.org/docs/latest/api/crypto.html#cryptocreatesignalgorithm-options
openssl list -digest-algorithms(TL;DR: always useSHA256)openssl ecparam -list_curves(secp256k1,prime256v1: X9.62/SECG, a.k.asecp256r1a.k.a.P-256)openssl list -public-key-algorithms(1.3.101.112, ED25519,1.2.840.10045.2.1, EC, id-ecPublicKey)
Node WebCrypto Key Gen Example
'use strict';
let Fs = require('node:fs/promises');
async function generateKeyPair(algo) {
let keyPair = await crypto.subtle.generateKey(algo, true, ['sign', 'verify']);
let privateKeyAb = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
let privateKeyDER = new Uint8Array(privateKeyAb);
let privateKeyPath = `./key.${algo.name}.der`.toLowerCase();
await Fs.writeFile(privateKeyPath, privateKeyDER);
let publicKeyAb = await crypto.subtle.exportKey('spki', keyPair.publicKey);
let publicKeyDER = new Uint8Array(publicKeyAb);
let publicKeyPath = `./pub.${algo.name}.der`.toLowerCase();
await Fs.writeFile(publicKeyPath, publicKeyDER);
console.info(`Key pair generated and saved as ${privateKeyPath} and ${publicKeyPath}`);
}
async function main() {
await generateKeyPair({ name: 'Ed25519' });
await generateKeyPair({ name: 'ECDSA', namedCurve: 'P-256' });
}
main().catch(function (err) {
console.error(err.stack);
process.exit(1);
});
Adapted From https://www.iana.org/assignments/cose/cose.xhtml
OKP (EdDSA / ed25519)
| Key Type | Name | COSE Label | Type | Description | Reference |
|---|---|---|---|---|---|
| 1 | crv | -1 | int / tstr | EC identifier | [RFC9053] |
| 1 | x | -2 | bstr | Public Key | [RFC9053] |
| 1 | d | -4 | bstr | Private key | [RFC9053] |
EC (ECDSA, secp256k1)
| Key Type | Name | COSE Label | Type | Description | Reference |
|---|---|---|---|---|---|
| 2 | crv | -1 | int / tstr | EC identifier | [RFC9053] |
| 2 | x | -2 | bstr | x-coordinate | [RFC9053] |
| 2 | y | -3 | bstr / bool | y-coordinate | [RFC9053] |
Modern Keypairs
These are the key types that are still relevant in 2024+ and will be relevant for the next decade:
let coseMap = {
"keys": {
"kty": 1,
"alg": 3
},
"okp": {
"crv": "-1",
"x": "-2",
"d": "-4"
},
"ec": {
"crv": "-1",
"x": "-2",
"y": "-3",
"d": "-4"
},
"kty": {
"1": "OKP",
"2": "EC"
},
"alg": {
"-47": "ES256K",
"-8": "EdDSA",
"-7": "ES256"
},
"crv": {
"1": "P-256",
"6": "Ed25519",
"8": "secp256k1"
}
};
Legacy Keypairs
let coseMap = {
"keys": {
"kty": 1,
"alg": 3
},
"okp": {
"crv": "-1",
"x": "-2",
"d": "-4"
},
"ec": {
"crv": "-1",
"x": "-2",
"y": "-3",
"d": "-4"
},
"rsa": {
"n": "-1",
"e": "-2",
"d": "-3",
"p": "-4",
"q": "-5",
"dp": "-6",
"dq": "-7",
"qi": "-8"
},
"kty": {
"1": "OKP",
"2": "EC",
"3": "RSA"
},
"alg": {
"-259": "RS512",
"-258": "RS384",
"-257": "RS256",
"-39": "PS512",
"-38": "PS384",
"-37": "PS256",
"-36": "ES512",
"-35": "ES384",
"-47": "ES256K",
"-8": "EdDSA",
"-7": "ES256"
},
"crv": {
"1": "P-256",
"2": "P-384",
"3": "P-521",
"6": "Ed25519",
"8": "secp256k1"
}
};
RSA (legacy)
RSA's not bad or broken, it's just not efficient.
| Key Type | Name | COSE Label | Type | Description | Reference |
|---|---|---|---|---|---|
| 3 | n | -1 | bstr | RSA modulus n |
[RFC8230] |
| 3 | e | -2 | bstr | RSA public exponent e |
[RFC8230] |
| 3 | d | -3 | bstr | RSA private exponent d |
[RFC8230] |
| 3 | p | -4 | bstr | Prime factor p of n |
[RFC8230] |
| 3 | q | -5 | bstr | Prime factor q of n |
[RFC8230] |
| 3 | dP | -6 | bstr | dP is d mod (p - 1) |
[RFC8230] |
| 3 | dQ | -7 | bstr | dQ is d mod (q - 1) |
[RFC8230] |
| 3 | qInv | -8 | bstr | CRT coefficient q^(-1) mod p |
[RFC8230] |
| 3 | other | -9 | array | Other prime infos, an array | [RFC8230] |
| 3 | r_i | -10 | bstr | Prime factor r_i of n, where i >= 3 |
[RFC8230] |
| 3 | d_i | -11 | bstr | d_i = d mod (r_i - 1) |
[RFC8230] |
| 3 | t_i | -12 | bstr | CRT coefficient t_i = (r_1 * r_2 * ... * r_(i-1))^(-1) mod r_i |
[RFC8230] |
- Dominant language
- JavaScript
- Stars
- 2
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from BeyondCodeBootcamp/passkeys
-
Difficulty 2/5 1-3 hours Newbie friendliness 25/100
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
Difficulty 4/5 3-5 days Newbie friendliness 28/100
BeyondCodeBootcamp/passkeys#6 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
All issues in BeyondCodeBootcamp/passkeys
Similar issues
-
bug confirmed issue
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
open-webui/open-webui#30750 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Mend: dependency security vulnerability untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 70/100