Node.js HTTPS and SSL Certificate for Development

August 22, 2014 (10y ago)

HTTPS is the HTTP protocol over TLS/SSL and HTTPS is required to protect your data. It is the most popular network protocol for establishiing secure connections for exchanging documents on the internet. It is basically HTTP carried over a TCP socket, which has been secured using SSL. Transport Layer Security (TLS) and Secure Sockets Layer (SSL) are cryptographic protocols designed to provide communication security. In this post I'll show how to create a self-signed SSL certificate and set up an express 4.0 project that uses it for local development purposes.

Self-Signed SSL Certificate

There are two kinds of certificates: those signed by a 'Certificate Authority', or CA, and 'self-signed certificates'. A Certificate Authority is a trusted source for an SSL certificate, and using a certificate from a CA allows your users to be trust the identity of your website. In most cases, you would want to use a CA-signed certificate in a production environment - for testing purposes, however, a self-signed certicate will do just fine.

To genereate a certificate all you need is openssl

$ where openssl
/usr/bin/openssl  /usr/local/bin/openssl

You can install it using homewbrew brew install openssl on Mac OS, on linux use sudo apt-get install openssl, on windows you can use this installer.

To update openssl on mac os run the following commands

brew update
brew install openssl
brew link --force openssl

Run the these commands to generate a self-signed certificate.

openssl genrsa -out key.pem
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
rm csr.pem

You will get a cert.pem (the certificate) and key.pem (the private key). This is all you need for a SSL connection.

In the second command, when prompted for "Common Name (eg, YOUR name) []:", do not give your name. It is actually the domain name field, so enter your domain name. Not giving your domain name will result in "domain mismatch" errors.

This certificate will trigger warnings in your browser, since it is self-signed.

When generating the key you might encounter the following error: unable to write 'random state', the most common reason for this happening seems to be that the .rnd file in your home directory is owned by root rather than your account. more on stackoverflow

Create an HTTPS Server

The HTTPS server and client API is almost identical to the HTTP API, so pretty much everything said above applies to them. In fact, the client API is the same, and the HTTPS server only differs in that it needs a certificate file.

Secure Server

var https = require('https');
var fs = require('fs');
 
var pkey = fs.readFileSync('key.pem');
var pcert = fs.readFileSync('cert.pem')
 
var options = {
    key: pkey,
    cert: pcert
};
 
var server = https.createServer(options, function (req, res) {
    res.writeHead(200);
    res.end("hello world\n");
}).listen(443);

Socket.io Client lang:javascript

var socket = io.connect('https://localhost:443/',{secure: true});

 

Nodejitsu http://docs.nodejitsu.com/articles/HTTP/servers/how-to-create-a-HTTPS-server NODE PRO TIP: Note fs.readFileSync - unlike fs.readFile, fs.readFileSync will block the entire process until it completes. In situations like this - loading vital configuration data - the sync functions are okay. In a busy server, however, using a synchronous function during a request will force the server to deal with the requests one by one!

For a complete guide to OpenSSL I highly recommend this article by Digital Ocean: OpenSSL Essentials: Working with SSL Certificates, Private Keys and CSRs

References