npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gjw-ec-key

v0.0.5

Published

Wrapper around an Elliptic Curve private or public keys

Downloads

14

Readme

Elliptic Curve Keys

This project defines a wrapper for Elliptic Curve (EC) private and public keys.

Curves

This wrapper supports onl the three main curves listed below:

| OpenSSL Curve Name | RFC-7518 (6.2.1.1) | ASN.1 OID | | ------------------ | ----------------------- | ------------------- | | prime256v1 | P-256 | 1.2.840.10045.3.1.7 | | secp384k1 | P-256K non standard | 1.3.132.0.10 | | secp384r1 | P-384 | 1.3.132.0.34 | | secp521r1 | P-521 | 1.3.132.0.35 |

Both the OpenSSL names and RFC-7518 (JWA/JWK) names can be used as parameters to the methods in the ECKey class.

Please be aware that NodeJS (and OpenSSL) support a large number of curves (see openssl ecparam -list_curves for a full list), but for brevity this implementation restricts to the three mentioned above.

PLEASE NOTE: The P-256K curve name (crv parameter) used when serializing a key using the secp384k1 curve is not standard, and NOT interoperable with other systems.

See the IANA registry for all known (and interoperable) curve names.

The P-256K name used might change at ANY time.

Basic construction

To use, start importing the main ECKey class:

const ECKey = require('ec-key');

Randomly generated keys

To create a random ECKey instance simply call the createECKey static method, optionally specifying a curve name (defaults to prime256v1):

// Create a new (random) ECKey instance using the secp521r1 curve
var randomKey = ECKey.createECKey('P-521');

Instantiating from encoded keys

To import an existing private or public key, simply invoke the constructor with a String or a Buffer and the format in which the key is encoded:

// Create a new ECKey instance from a base-64 spki string
var key = new ECKey('MFkwEw ... 3w06qg', 'spki');

For Buffers and base64-encoded Strings the constructor supports both the pkcs8 (or rfc5208) and spki (or rfc5280) formats.

Additionally, the pem format is supported for unencoded Strings and Buffers:

// Load up a PEM file and wrap it into a
var pem = fs.readFileSync('./key.pem');
var key = new ECKey(pem, 'pem');

Instantiating with objects

Instances of the ECKey class can also be created from very simple object.

For example JWKs can be used directly, and whereas in the example below the crv, x and y values will be considered, kty and kid will be ignored.

/// Simply create from a JWK object
var key = new ECKey({
  "kty":"EC",
  "crv":"P-256",
  "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
  "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
  "kid":"Public key used in JWS spec Appendix A.3 example"
})

The following values are recognized:

  • curve or crv: the curve type for this key, identified either by its OpenSSL or its RFC-7518 (JWA/JWK) name.

With regards to coordinates:

  • d: the private d coordinate for the elliptic curve point, either as a Buffer, or a base64-encoded String of the coordinate's big endian representation
  • x: the public x coordinate for the elliptic curve point, either as a Buffer, or a base64-encoded String of the coordinate's big endian representation
  • y: the public y coordinate for the elliptic curve point, either as a Buffer, or a base64-encoded String of the coordinate's big endian representation

And also:

  • publicKey: the uncompressed and prefixed (0x04) concatenation of the x and y public coordinates' big endian representation, as described in SEC-1 ECC section 2.3.3
  • privateKey: the private d coordinate for the elliptic curve point, either as a Buffer, or a base64-encoded String of the coordinate's big endian representation

ECKey properties

The following enumerable properties are available for instances of ECKey:

  • curve: the EC key curve name in OpenSSL format (e.g. prime256v1)
  • isPrivateECKey: a boolean indicating whther this instance represents a private or public EC key.
  • x: the public x coordinate's big endian representation for the elliptic curve point as a Buffer
  • y: the public y coordinate's big endian representation for the elliptic curve point as a Buffer
  • d: the private d coordinate's big endian representation for the elliptic curve point as a Buffer

Additionally the following properties are available, but not enumerable:

  • jsonCurve: the EC key curve name in RFC-7518 format (e.g. P-256)
  • publicCodePoint: the uncompressed and prefixed (0x04) concatenation of the x and y public coordinates' big endian representation, as described in SEC-1 ECC section 2.3.3.

ECKey functions

asPublicECKey()

Return this instance if this key is a public key, or create a new ECKey instance not including the private components of the key.

computeSecret(otherKey)

A simple shortcut for createECDH().computeSecret(otherKey) as explained below.

createECDH()

Create a standard Node ECDH object instance whose computeSecret(...) function accepts also ECKey (as in, this class) instances.

createSign(hash)

Create a standard Node Sign object whose sign(...) function is automatically populated with this instance.

  • hash: the hashing function to use for generating the signature, normally one of SHA256, SHA384 or SHA512.
// Create a signature of the message "the quick brown fox" with a random key
var message = "the quick brown fox";
var key = ECKey.createECKey('P-384');
var signature = key.createSign('SHA384')
                   .update(message)
                   .sign('base64');

createVerify(hash)

Create a standard Node Verify object whose verify(...) function is automatically populated with this instance.

  • hash: the hashing function to use for generating the signature, normally one of SHA256, SHA384 or SHA512.
// Verify the signature calcuated above
key.createVerify('SHA384')
   .update(message)
   .verify(signature, 'base64');

toBuffer(format)

Encode this EC key, optionally using the specified format (defaults to pem).

Formats supported are as follows:

  • pem: return a Buffer containing the ascii represtation of the OpenSSL PEM format
    • equivalent to new Buffer(key.toString('pem'), 'ascii') and provided for convenience only
  • rfc5951: (private keys only) returns the encoding of this key as specified by RFC-5951
  • pkcs8 or rfc5208: (private keys only) returns the PKCS8 encoding of this key as specified by RFC-5208
  • spki or rfc5280: (public keys only) returns the SPKI encoding of this key as specified by RFC-5280

toString(format)

Encode this EC key, optionally using the specified format (defaults to pem).

Formats supported are as follows:

  • pem: return the key in OpenSSL's PEM format
  • rfc5951: (private keys only) returns the encoding of this key as specified by RFC-5951, wrapped with a header and footer as outlined in section 4
  • pkcs8 or rfc5208: (private keys only) returns the PKCS8 encoding of this key as specified by RFC-5208 encoded in base64
  • spki or rfc5280: (public keys only) returns the SPKI encoding of this key as specified by RFC-5280 encoded in base64

toJSON()

Formats this ECKey as a JSON Web Key as specified by RFC-7517.

Please note that his function will also be called by the JSON.stringify(...) function.

// Convert a PEM to a JWK in one easy step

var pem = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgzr+Twxehecu0VYoC
XUBL1Z4h3H28gPnJ5MP0AcOixAOhRANCAAS6pMWMMndZxOPSC9ui6sUUbmeK6dIi
k3ZwTmm0SE7G+tYon5C57aVek5qH4y4OipbSLfbsIQuOkt0G8Vu1KZ3u
-----END PRIVATE KEY-----`;

var key = new ECKey(pem, 'pem');

var jwk = JSON.stringify(key, null, 2);

console.log(jwk);

// This will result in the following output:
// {
//   "kty": "EC",
//   "crv": "P-256",
//   "x": "uqTFjDJ3WcTj0gvbourFFG5niunSIpN2cE5ptEhOxvo",
//   "y": "1iifkLntpV6TmofjLg6KltIt9uwhC46S3QbxW7Upne4",
//   "d": "zr-Twxehecu0VYoCXUBL1Z4h3H28gPnJ5MP0AcOixAM"
// }