Learn how to create self-signed .pem certificates required to create a secure connection with a Node.js server or express server

If you're working with web servers in Node.js you may probably already wanted to create a secure connection, either to provide indeed a secure connection or to allow the access of APIs in the browser that only are accessible if the protocol is HTTPS and not HTTP e.g getUserMedia or webkitSpeechRecognition etc.

The task of create a web server with secure protocol using either the http server module of Node.js or a framework like Express (that's what we are going to use in this case) is pretty simple:

// server.js
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey  = fs.readFileSync('certificates/key.pem', 'utf8');
var certificate = fs.readFileSync('certificates/cert.pem', 'utf8');

var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();

// your express configuration here

var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);

// For http
httpServer.listen(8080);
// For https
httpsServer.listen(8443);

app.get('/', function (req, res) {
    res.header('Content-type', 'text/html');
    return res.end('<h1>Hello, Secure World!</h1>');
});

Note: although 443 is the default port for HTTPS, during the development use something like 8443 because most systems don't allow to run non-root listeners on low-numbered ports.

As you can see, we just need to provide a valid path for the key and cert properties with valid pem certificates. However, the most of us don't know what are those files (well, at least, i didn't know ... maybe you do ... if so, what are you doing here ?).

A PEM file or Privacy Enhanced Mail is a Base64 encoded certificate. This kind of certificates are frequently used for web servers as they can easily be translated into readable data using any text editor. This file contains very distinct headers and footers. This is a container format that may include just the public certificate (such as with Apache installs, and CA certificate files /etc/ssl/certs), or may include an entire certificate chain including public key, private key, and root certificates.

As we are in the development stage, you may probably don't want to pay for a trusted certificate, therefore we are going to create our self-signed certificated for development and testing purposes only in this article.

Requirements

You will need the openssl utility and we are going to access it through a terminal and commands, in this case we are using GnuWin32 from SourceForge and the executable of openssl will be located in C:\Program Files\GnuWin32\bin\openssl.exe, therefore we just need to navigate with a new command prompt to the bin folder and there we'll execute the commands:

cd C:\Program Files\GnuWin32\bin
REM then after execute the previous command, you will use openssl here
REM For example: openssl req -newkey .....................

If you are using other platform, please refer for more information about how to use openssl in other operative systems in Google.

To create an SSL certificate you first need to generate a private key (key.pem) and a certificate signing request (cert.pem), or CSR (which also contains your public key). You can do this in different ways, but as previously mentioned, we are going to use OpenSSL which is very easy to use.

Implementation

Execute the following command and change the path of the keyout and out parameter (if you want) the path where the key should be created:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout c:/key.pem -out c:/cert.pem

While using GnuWin32, you may be probably found the following error if you execute the previous command:

Unable to load config info from /usr/local/ssl/openssl.cnf

To solve it, we need to provide the path to the mentioned file using the -config parameter with the path of the openssl.cnf file. The path of this file may vary (with a default installation should be C:\Program Files\GnuWin32\share\openssl.cnf), therefore search for this file in the folder where GnuWin32 is installed and once you get the absolute path provide the path as parameter using:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout c:/key.pem -out c:/cert.pem -config C:\Program Files\GnuWin32\share\openssl.cnf

If you don't get any error, now the interactive prompt will start and will ask for basic information about your certificate. Once you have filled all the information, you should get 2 files key.pem and cert.pem that in this case with our command will be located in c:\.

Copy the path of these files (or copy the files into a known directory of your project) and provide them as shown in the script at the beginning of the article (or your own script). The execution of node server.js with our script should allow you to navigate to https://localhost:8443 in your browser and (as expected because our certificate isn't trusted as it's self-signed) your should see the following warning (in this case for Chrome):

Chrome Untrusted Certificate example

Click on Advanced and click on Proceed to localhost (unsafe) and there you go !

Secure World Message Https Express

Your https server with Express (or the http module) has been correctly implemented.

Creating a trusted certificate (optional)

Execute the following command and change the path of the keyout and out parameter (if you want) the path where the key should be created:

openssl req -newkey rsa:2048 -new -nodes -keyout c:/key.pem -out c:/csr.pem

If you get again the "Unable to load error .." refer to the implementation in the previous area. If you don't get any error, now the interactive prompt should start and will ask for basic information about your certificate. Once you have filled all the information, you should get 2 files key.pem and csr.pem that in this case with our command will be located in c:\. The csr.pem file should be submitted to any valid Certificate Authority like Comodo , Symantec, GoDaddy or other entity that issues digital certificates if you want to buy a SSL certificate. Once you do all the process you should receive a valid certificate. Use that certificate with your Node.js server.

Happy coding ❤️!


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors