Difference Between Root, Intermediate and Server SSL Certificate

How to avoid SSL Chain error and sample SSL NodeJS Implementation

2017-02-20

I integrated the Secret Key file and the Server Certificate that I purchased in my NodeJS application. The server started up without any errors and when I accessed it through HTTPS, Google Chrome showed me that nice green bar.

But when our Android developer tried to access the server it gave him the following error:

1
"javax.net.ssl.SSLHandshakeException: Connection closed by peer"

Since, none of Google Chrome and NodeJS server wasn’t giving me error, I wanted to check if my SSL chain is set up properly. Digicert provides you with a neat little tool to verify your SSL setup. It showed me that my certificate chain is not properly installed.

What is SSL Chain?

Certificate signing authority provides you with three types of certificates:

  1. Root Certificate
  2. Server Certificate
  3. Intermediate Certificate

Root Certificate is the one that belongs to the certificate signing authority. Server Certificate is the one that is provided to you and you install it on your server.

Client requires an SSL chain which links your server to the server signing authority that you got your certificate from. But Root Certificate must be secured and is put behind multiple layers of security. So, what the signing authority does is give out an Intermediate Certificate that you install on your server along with your Server Certificate. This Intermediate Certificate links the client to the certificate signing authority.

Where do I install the Intermediate Certificate?

To install the Intermediate Certificate, simply append the intermediate certificate beneath your Server Certificate file and import that file just like you would any other Server Certificate.

An example NodeJS certificate implementation is shown below. In the following example, server.crt contains Server Certificate and Intermediate Certificate in the single file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

var http = require('http');
var https = require('https');

var options = {
key : fs.readFileSync('./config/server.key'),
cert : fs.readFileSync('./config/server.crt')
};

var httpsServer = https.createServer(options, app).listen(process.env.HTTPS_PORT || 8000);

// Redirect HTTP traffic to HTTPS
var httpServer = http.createServer(function (req, res) {
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url});
res.end();
}).listen(process.env.HTTP_PORT || 5000);

It’s also a good idea to listen to HTTP traffic and route it to HTTPS.