node-kms
v0.4.0
Published
A client implementation of the Key Management Service (KMS) for JavaScript -- for both node.js and browser.
Downloads
40,625
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].
Installing
To install the latest from NPM:
npm install node-kms
Or to install a specific release:
npm install [email protected]
Alternatively, the latest unpublished code can be installed directly from the repository:
npm install git+ssh://[email protected]: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 KMSrequestId
-- the unique id for this requesturi
-- 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 KMSrequestId
-- the id for the corresponding requeststatus
-- the status code of the responsereason
-- 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;
});