Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

client-authenticated-https

1.0.1-beta.0 • Public • Published
93 Million Ltd. logo
Client Authenticated HTTPS logo

Client Authenticated HTTPS

HTTPS communication authenticated using client as well as server SSL certificates

What is Client Authenticated HTTPS?

Client Authenticated HTTPS is a Node.JS library. It is useful when you want to guarantee that only authenticated clients can communicate with a server using HTTPS encryption.

Generate keys for both the server and the clients then use this library as a drop-in replacement anywhere you have used https.request(), https.get(), and https.createServer().

Client keys are single files that can be easily installed by placing in a directory on the client to grant access to the server.

This library is open source under the MIT license and has good coverage with unit tests and integration tests.

Getting started

Requirements

openssl must be installed and present in your path to generate keys. It is included in most distributions.

Works with Node v12 or later

Setting up keys

Create a directory named cahkeys to hold server and client keys. A good place to put this directory is in your project root directory.

Generating a server key

Generate the server key using the command:

npx client-authenticated-https create-key --server --keydir /path/to/cahkeys --name <server-hostname>

There can be only 1 server key. Running the command again will overwrite any existing server keys.

The value <server-hostname> passed to --name must match the host name the clients will use to connect to the server or a connection will not be established. Currently, <server-hostname> can only be a single, fixed hostname. Wildcards or alternative names are not currently supported. If you omit --name the default name 'localhost' will be used.

Take a look in your cahkeys directory - you will now see server.cahkey

$ ls -la /path/to/cahkeys/
total 16
drwxr-xr-x  3 pommy  staff    96  4 Sep 22:13 .
drwxr-xr-x  9 pommy  staff   288  4 Sep 21:48 ..
-rw-r--r--  1 pommy  staff  7857  4 Sep 21:09 server.cahkey

Generating client keys

Generate a client key using the command:

npx client-authenticated-https create-key --keydir /path/to/cahkeys --name client

There can be as many client keys as you require. You can chose to give each client a unique key or share a key between many clients.

If you omit --name the default name 'client' will be used. Unlike the server key, it is not required that the value <client-name> passed to --name matches any of the network credentials of the client to establish a connection.

NB: The server key is effectively the master key. All client keys are generated from the server key. If you regenerate the server key you will need to regenerate all the client keys!!! For this reason it may be worth making a secure backup of the server key.

Take a look in your cahkeys directory - you will now see client.cahkey

$ ls -la cahkeys/
total 32
drwxr-xr-x  4 pommy  staff   128  4 Sep 21:10 .
drwxr-xr-x  9 pommy  staff   288  4 Sep 21:48 ..
-rw-r--r--  1 pommy  staff  5372  4 Sep 21:10 client.cahkey
-rw-r--r--  1 pommy  staff  7857  4 Sep 21:09 server.cahkey

You can generate as many client keys as you wish, however if you have more than 1 you will need to specify which to use when making a request.

Using the library

The API extends Node's https with 2 methods overridden: .request() and .createServer(). Both these methods have the same signature as they do in the https library, however an important difference is that they are async methods.

See the node documentation for information about how to use these methods:

Creating a server

Let's review how to migrate the following server, written using the standard https library, to clientAuthenticatedKeys:

const https = require('https')
 
exports = () => {
  https.createServer(
    {
      cert: fs.readFileSync('/path/to/cert/fullchain.pem'),
      key: fs.readFileSync('/path/to/cert/privkey.pem')
    },
    (req, res) => {
      …
    }
  ).listen(443)
}

The following changes need to be made:

  • Require client-authenticated-https instead of https
  • await on .createServer() before chaining the returned value to .listen(443)
  • Update the enclosing function to use async (or alternativly use clientAuthenticatedHttps.createServer() as a promise)
  • Remove SSL options related to cert, key and ca as these are replaced by the keys generated by npx client-authenticated-https create-key
const clientAuthenticatedHttps = require('client-authenticated-https')
 
exports = async () => {
  (await clientAuthenticatedHttps.createServer(
    (req, res) => {
      …
    }
  )).listen(443)
}

Creating a client

Install the client key on the client:

  • Create a directory in your project root named cahkeys
  • Copy the file client.cahkey you created from the server into this directory

If you want to place the cahkeys directory in a custom location, use an env var

Let's review how to migrate the following request, written using the standard https library, to clientAuthenticatedKeys:

const https = require('https')
 
exports = () => {
  const req = https.request(
    {
      url: 'https://secure.example.com/',
      …
    },
    (res) => { … }
  )
 
  req.write(postData)
  req.end()
}

The following changes need to be made:

  • Require client-authenticated-https instead of https
  • await on .request() before calling further methods on the returned request object
  • Update the enclosing function to use async (or alternativly use clientAuthenticatedHttps.request() as a promise)
  • Optionally specify the name of the cahkey to use to make the request. This is useful if there is more than 1 client key in your cahkeys directory. Do not include the .cahkey file extension. A cahkey can also be defined by setting the environment variable CAH_KEY_NAME (again, without extension).
const clientAuthenticatedHttps = require('client-authenticated-https')
 
exports = async () => {
  const req = await clientAuthenticatedHttps.request(
    {
      url: 'https://secure.example.com/',
      cahkey: 'my-special-key',
      …
    },
    (res) => { … }
  )
 
  req.write(postData)
  req.end()
}

Examples

Look in ./example/ for a working example of a server and client

Specifying a custom location for the cahkeys directory

The cahkeys directory is located by progressing back through the filesystem from the client-authenticated-https directory until a cahkeys directory is found. You can specify a directory at an alternative location by supplying a path to the directory in the env var CAH_KEY_DIR.

Tests

Run unit tests:

npm run test:unit

Run integration tests:

npm run test:sit

Run all tests:

npm test

License and copyright

All logos, images and artwork are copyright 93 Million Ltd. and used by permission for this project only.

Code is released under the MIT license

Copyright 93 Million Ltd. All rights reserved

93 Million Ltd. logo

Install

npm i client-authenticated-https

DownloadsWeekly Downloads

2

Version

1.0.1-beta.0

License

MIT

Unpacked Size

327 kB

Total Files

36

Last publish

Collaborators

  • avatar