Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@root/keypairs

Package Overview
Dependencies
Maintainers
3
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@root/keypairs

Lightweight, Zero-Dependency RSA and EC/ECDSA crypto for Node.js and Browsers

  • 1.0.0-wip.0
  • next
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
11K
decreased by-21.46%
Maintainers
3
Weekly downloads
 
Created
Source

@root/keypairs

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 (and SSH-to-JWK)
  • JWK-to-PEM (and JWK-to-SSH)
  • Create JWTs (and sign JWS)
  • SHA256 JWK Thumbprints
  • JWK fetching. See Keyfetch.js
    • OIDC
    • Auth0
  • CLI

Progress

This is fully functional, but the re-usable code from ACME.js hasn't been fully teased out for the v2.0 release.

(SSH conversions have not yet made it to 2.0)

Usage

A brief introduction to the APIs:

// generate a new keypair as jwk
// (defaults to EC P-256 when no options are specified)
Keypairs.generate().then(function(pair) {
	console.log(pair.private);
	console.log(pair.public);
});
// JWK to PEM
// (supports various 'format' and 'encoding' options)
return Keypairs.export({ jwk: pair.private, format: 'pkcs8' }).then(function(
	pem
) {
	console.log(pem);
});
// PEM to JWK
return Keypairs.import({ pem: pem }).then(function(jwk) {
	console.log(jwk);
});
// Thumbprint a JWK (SHA256)
return Keypairs.thumbprint({ jwk: jwk }).then(function(thumb) {
	console.log(thumb);
});
// Sign a JWT (aka compact JWS)
return Keypairs.signJwt({
  jwk: pair.private
, iss: 'https://example.com'
, exp: '1h'
  // optional claims
, claims: {
  , sub: 'jon.doe@gmail.com'
  }
});

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

  • generate (JWK)
  • parse (PEM)
  • parseOrGenerate (PEM to JWK)
  • import (PEM-to-JWK)
  • export (JWK-to-PEM, private or public)
  • publish (Private JWK to Public JWK)
  • thumbprint (JWK SHA256)
  • signJwt
  • signJws
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.parse(options)

Parses either a JWK (encoded as JSON) or an x509 (encdode as PEM) and gives back the JWK representation.

Option Examples:

  • JWK { key: '{ "kty":"EC", ... }' }
  • PEM { key: '-----BEGIN PRIVATE KEY-----\n...' }
  • Public Key Only { key: '-----BEGIN PRIVATE KEY-----\n...', public: true }
  • Must Have Private Key { key: '-----BEGIN PUBLIC KEY-----\n...', private: true }

Example:

Keypairs.parse({ key: '...' }).catch(function(e) {
	// could not be parsed or was a public key
	console.warn(e);
	return Keypairs.generate();
});
Keypairs.parseOrGenerate({ key, throw, [generate opts]... })

Parses the key. Logs a warning on failure, marches on. (a shortcut for the above, with private: true)

Option Examples:

  • parse key if exist, otherwise generate { key: process.env["PRIVATE_KEY"] }
  • generated key curve { key: null, namedCurve: 'P-256' }
  • generated key modulus { key: null, modulusLength: 2048 }

Example:

Keypairs.parseOrGenerate({ key: process.env['PRIVATE_KEY'] }).then(function(
	pair
) {
	console.log(pair.public);
});

Great for when you have a set of shared keys for development and randomly generated keys in

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.publish({ jwk: jwk, exp: '3d', use: 'sig' })

Promises a public key that adheres to the OIDC and Auth0 spec (plus expiry), suitable to be published to a JWKs URL:

{ "kty": "EC"
, "crv": "P-256"
, "x": "..."
, "y": "..."
, "kid": "..."
, "use": "sig"
, "exp": 1552074208
}

In particular this adds "use" and "exp".

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
  // required claims
, iss: 'https://example.com'
, exp: '15m'
  // all optional claims
, claims: {
  }
}

Exp may be human readable duration (i.e. 1h, 15m, 30s) or a datetime in seconds.

Header defaults:

{ kid: thumbprint
, alg: 'xS256'
, typ: 'JWT'
}

Payload notes:

  • iat: now is added by default (set false to disable)
  • exp must be set (set false to disable)
  • iss should 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:

  • header not what you think. Leave undefined unless you need this for the spec you're following.
  • protected is the typical JWT-style header
    • kid and alg will be added by default (these are almost always required), set false explicitly to disable
  • payload can 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 for the following:

  • generate(options)
  • import({ pem: '---BEGIN...' })
  • export({ jwk: { kty: 'EC', ... })
  • thumbprint({ jwk: jwk })

If you want to know the algorithm-specific options that are available for those you'll want to take a look at the corresponding documentation:

Keywords

FAQs

Package last updated on 08 Oct 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc