Note:
- Browser WebCrypto only supports P-256
- Node
node:crypto and WebCrypto also supports Ed25519 and secp256k1 (as just SHA256) - whatever is supported by openssl v3
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] |
Note:
node:cryptoand WebCrypto also supports Ed25519 and secp256k1 (as justSHA256) - whatever is supported by openssl v3openssl 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
Adapted From https://www.iana.org/assignments/cose/cose.xhtml
OKP (EdDSA / ed25519)
EC (ECDSA, secp256k1)
Modern Keypairs
These are the key types that are still relevant in 2024+ and will be relevant for the next decade:
Legacy Keypairs
RSA (legacy)
RSA's not bad or broken, it's just not efficient.
nedpofnqofndPisdmod (p - 1)dQisdmod (q - 1)q^(-1)modpr_iofn, wherei >= 3d_i = dmod (r_i - 1)t_i = (r_1 * r_2 * ... * r_(i-1))^(-1)modr_i