Client Authentication using NodeJs

2018-03-03

Enforcing client authentication via NodeJs is simple quick & efficient.

Below I will demonstrate how to setup a server running NodeJs that performs client certification authentication which will reject any requests not made with a valid certificate.

Firstly, install NodeJs, then run:

 npm install

This will install a basic packages file for use with the node application

Create an empty file called app.js - this will contain the code required for server authentication

Create the following folder locations on the server ca/certs/client-auth/ and ca/crl/

We need to acquire some internal packages, paste the following at the start of the app.js file

 var fs = require("fs"), 
 http = require("http"), 
 https = require("https"), 
 httpProxy = require("http-proxy"), 
 proxy = httpProxy.createProxyServer();

Next we need to retrieve a list of valid root certificates along with a certificate revocation list. The CRL will ensure that revoke certificates are handled appropriately

 var clientCertificates = []; 
 var revocationCertificateLists = []; 
 var clientcertAuths = fs.readdirSync("ca/certs/client-auth"); 
 var crls = fs.readdirSync("ca/crl"); 
 for (var index = 0; index < clientcertAuths.length; index++) { 
        clientCertificates[index] = fs.readFileSync("ca/certs/client-auth/" + clientcertAuths[index]); 
 } 
 for (var index = 0; index < crls.length; index++) {
        revocationCertificateLists[index] = fs.readFileSync("ca/crl/" + crls[index]); 
 }

We need to set the several options for use on our server, these options will allow for certificate authentication and HTTPS

 var options = { 
    "pfx": fs.readFileSync("ca/certs/server.pfx"), 
    "ciphers": "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS", 
    "honorCipherOrder": true,
    "crl": revocationCertificateLists,
    "ca": clientCertificates,
    "requestCert": true,
    "rejectUnauthorized": true
 };

The options used are defined on the NodeJs website

Lastly we need to create the server and set the port that we want to use for HTTPS traffic

 https.createServer(options, (req, res) => {
    console.log("Hello HTTPS traffic ");
 }).listen(443);

Now create your root certificate from which all client certificates will be created and store that file in ca/certs/client-auth and all certificate revocation files to be stored in ca/crl/