Keypairs for node.js
Lightweight JavaScript RSA and ECDSA utils that work on Windows, Mac, and Linux using modern node.js APIs (no need for C compiler).
A thin wrapper around Eckles.js (ECDSA) and Rasha.js (RSA).
Features
- Generate keypairs
- RSA
- ECDSA (P-256, P-384)
- PEM-to-JWK
- JWK-to-PEM
- SHA256 JWK Thumbprints
- JWK fetching. See Keyfetch.js
- OIDC
- Auth0
Usage
A brief (albeit somewhat nonsensical) introduction to the APIs:
Keypairs.generate().then(function (pair) {
return Keypairs.export({ jwk: pair.private }).then(function (pem) {
return Keypairs.import({ pem: pem }).then(function (jwk) {
return Keypairs.thumbprint({ jwk: jwk }).then(function (thumb) {
console.log(thumb);
return Keypairs.signJwt({
jwk: keypair.private
, claims: {
iss: 'https://example.com'
, sub: 'jon.doe@gmail.com'
, exp: Math.round(Date.now()/1000) + (3 * 24 * 60 * 60)
}
});
});
});
});
});
By default ECDSA keys will be used since they've had native support in node much longer than RSA has, and they're smaller, and faster to generate.
API Overview
Keypairs.generate(options)
Generates a public/private pair of JWKs as { private, public }
Option examples:
- RSA
{ kty: 'RSA', modulusLength: 2048 } - ECDSA
{ kty: 'ECDSA', namedCurve: 'P-256' }
When no options are supplied EC P-256 (also known as prime256v1 and secp256r1) is used by default.
Keypairs.import({ pem: '...' }
Takes a PEM in pretty much any format (PKCS1, SEC1, PKCS8, SPKI) and returns a JWK.
Keypairs.export(options)
Exports a JWK as a PEM.
Exports PEM in PKCS8 (private) or SPKI (public) by default.
Options
{ jwk: jwk
, public: true
, encoding: 'pem' // or 'der'
, format: 'pkcs8' // or 'ssh', 'pkcs1', 'sec1', 'spki'
}
Keypairs.thumbprint({ jwk: jwk })
Promises a JWK-spec thumbprint: URL Base64-encoded sha256
Keypairs.signJwt({ jwk, header, claims })
Returns a JWT (otherwise known as a protected JWS in "compressed" format).
{ jwk: jwk
, claims: {
}
}
Header defaults:
{ kid: thumbprint
, alg: 'xS256'
, typ: 'JWT'
}
Payload notes:
iat: nowis added by default (setfalseto disable)expmust be set (setfalseto disable)issshould be the base URL for JWK lookup (i.e. via OIDC, Auth0)
Notes:
header is actually the JWS protected value, as all JWTs use protected headers (yay!)
and claims are really the JWS payload.
Keypairs.signJws({ jwk, header, protected, payload })
This is provided for APIs like ACME (Let's Encrypt) that use uncompressed JWS (instead of JWT, which is compressed).
Options:
headernot what you think. Leave undefined unless you need this for the spec you're following.protectedis the typical JWT-style headerkidandalgwill be added by default (these are almost always required), setfalseexplicitly to disable
payloadcan be JSON, a string, or even a buffer (which gets URL Base64 encoded)- you must set this to something, even if it's an empty string, object, or Buffer
Additional Documentation
Keypairs.js provides a 1-to-1 mapping to the Rasha.js and Eckles.js APIs,
but it also includes the additional convenience methods signJwt and signJws.
That is to say that any option you pass to Keypairs will be passed directly to the corresponding API of either Rasha or Eckles.