node-kms

A client implementation of the Key Management Service (KMS) for JavaScript -- for both node.js and browser.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
node-kms
2010.4.03 years ago9 years agoMinified + gzip package size for node-kms in KB

Readme

node-kms #
A JavaScript implementation of Key Management Service (KMS) for current web browsers and node.js-based servers. The KMS API is described in draft-abiggs-saag-key-management-service-02.

- Creating - Importing/Exporting - Obtaining a node-jose Key - Creating and Initializing - Generating an Ephemeral EC Key - Deriving an Ephemeral Shared Key - Creating - Wrapping - Creating - Unwrapping

Installing ##

To install the latest from NPM:
npm install node-kms

Or to install a specific release:
npm install node-kms@0.3.0

Alternatively, the latest unpublished code can be installed directly from the repository:
npm install git+ssh://git@github.com:cisco/node-kms.git

Basics ##

Require the library as normal:
var KMS = require('node-kms');

This library uses Promises for many operations.
This library supports Browserify. To use in a web browser, require('node-kms') and bundle with the rest of your app.

KeyObjects ##

A KMS KeyObject wraps a JSON Web Key (JWK) to provide more semantics: a URI to locate it; the creating user and client; the date/time of when a key is created, bound, and/or expires; and the owning resource (once bound).

Creating ###

To create an empty KeyObject:
var keyobj = new KMS.KeyObject();

None of the KMS.KeyObject properties are set.
Alternatively, to create a KeyObject from a JSON or POJO representation:
// {input} is one of:
// *  a JSON object (where date/times are RFC3339-encoded Strings)
// *  a POJO (where date/times are Date objects)
var keyobj = new.KeyObject(input);

Importing/Exporting ###

NOTE: The JSON representation includes all properties for a KeyObject, including the full JWK (if present). This can expose secret key material if not carefully handled; do not save to durable storage without protecting it (e.g., encrypting to a JWE).
To import a KeyObject from a JSON object:
// {input} is one of:
// *  a JSON object (where date/times are RFC3339-encoded Strings)
// *  a POJO (where date/times are Date objects)
// *  an existing KeyObject instance
keyobj = KMS.fromObject(input);

In the case where input is already a KeyObject, it is returned as-is.
To export a KeyObject to a JSON object:
var output = keyobj.toJSON();

Obtaining a node-jose Key ###

To convert the jwk property of a KeyObject to a node-jose Key (to use for encryption or signatures):
var jwk;
keyobj.asKey().
    then(function(result) {
      // {result} is a jose.JWK.Key
      jwk = result;
    });

If jwk is not set on the KeyObject, the returned Promise is rejected.

Contexts ##

The KMS.Context holds onto information necessary to wrap Requests and unwrap Responses.

Creating and Initializing ###

To create an empty Context:
var kmsCtx = new KMS.Contet();

None of the Context properties are set.
To finish initializing the Context, set the clientInfo and serverInfo properties:
// {clientId} is a String containing an identifier for the client or session
// {userId} is a String containing the user's identifier
// {oauth2token} is a String containing an OAuth2 Bearer token
kmsCtx.clientInfo = {
  clientId: clientId,
  credential: {
    userId: userId,
    bearer: oauth2token
  }
};
// {serverPublicKey} is a JWK JSON object
kmsCtx.serverInfo = {
  key: serverPublicKey
};

Generating an Ephemeral EC Key ###

To create a KeyObject representing the local ECDH key:
kmsCtx.createECDHKey().
    then(function(result) {
      // {result} is a KMS.KeyObject wrapping a "EC" JWK
      kmsCtx.ephemeralKey = result;
    })

Deriving an Ephemeral Shared Key ###

To derive an ephemeral shared key -- such as the result of the ECDHE handshake:
// {remoteECDH} is a KMS.KeyObject wrapping a "EC" JWK
kmsCrx.deriveEphemeralKey(remoteECDH).
    then(function(result) {
      // {result} is a KMS.KeyObject wrapping a "oct" JWK
      kmsCtx.ephemeralKey = result;
    });

Requests ##

The KMS.Request embodies a single request from a client to the KMS.
A Request instance has the following (read/write) properties:
  • body -- the full (plaintext) JSON to be sent to the KMS
  • requestId -- the unique id for this request
  • uri -- the URI of the request (e.g., "/ecdhe/", "/resources", etc.)
  • method -- the method (verb) for the request (e.g., "create", "retrieve", etc.)
  • wrapped -- the wrapped (encrypted) body

When a new body is set, the previous requestId, method, and uri are remembered, overwriting any new values that might have been in the provided JSON.

Creating ###

To create an empty request:
var request = new KMS.Request();

To create a request starting with a constructed body:
// {input} is a JSON object representing the request 
var request = new KMS.Request(input);

Wrapping ###

To wrap (encrypt) the Request into a JWE for transmitting to a KMS server, using an ephemeral shared key:
var output;
request.wrap(kmsCtx).
    then(function(result) {
      // {result} is a String of the JWE in the Compact Serialization
      // request.wrapped is also set to {result}
      output = result;
    });

Responses ##

The KMS.Response embodies a single response to a client from the KMS.
A Response instance has the following (read/write) properties:
  • body -- the full (plaintext) JSON received from the KMS
  • requestId -- the id for the corresponding request
  • status -- the status code of the response
  • reason -- the string reason (if any)
  • wrapped -- the protected (encrypted or signed) body

Creating ###

To create an empty KMS.Response:
var response = new KMS.Response();

To creat a KMS.Response with a received wrapped body:
// {input} is a String of the JWE (or JWS) using the Compact Serialization
var response = new KMS.Response(input);

Unwrapping ###

To unwrap a response into the plaintext body:
var input;
response.unwrap(kmsCtx).
    then(function(result) {
      // {result} is the plaintext JSON object
      // response.body is also set to {result}
      input = result;
    });