375
votes

Given an SSL key and certificate, how does one create an HTTPS service?

10
I used restify.js instead of express.js, but the idea is the same. Here's how I set up a node.js server that accepts both HTTP and HTTPS qugstart.com/blog/node-js/…awaage
without express and with the newest version of node - look here: stackoverflow.com/a/21809393/388026Philipp Kyeck
What happened to this question? The answers imply that it was originally about express.js.doug65536
it's trivial to create a valid, self-signed SSL cert and launch an HTTPS server, just a few stepsLloyd
Its a bit late but if someone need a complete nodejs https tutorial, can find here: programmerblog.net/nodejs-https-serverJason W

10 Answers

157
votes

I found following example.

https://web.archive.org/web/20120203022122/http://www.silassewell.com/blog/2010/06/03/node-js-https-ssl-server-example/

This works for node v0.1.94 - v0.3.1. server.setSecure() is removed in newer versions of node.

Directly from that source:

const crypto = require('crypto'),
  fs = require("fs"),
  http = require("http");

var privateKey = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();

var credentials = crypto.createCredentials({key: privateKey, cert: certificate});

var handler = function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
};

var server = http.createServer();
server.setSecure(credentials);
server.addListener("request", handler);
server.listen(8000);
499
votes

The Express API doc spells this out pretty clearly.

Additionally this answer gives the steps to create a self-signed certificate.

I have added some comments and a snippet from the Node.js HTTPS documentation:

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

// This line is from the Node.js HTTPS documentation.
var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.cert')
};

// Create a service (the app object is just a callback).
var app = express();

// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
89
votes

Found this question while googling "node https" but the example in the accepted answer is very old - taken from the docs of the current (v0.10) version of node, it should look like this:

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

var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);
48
votes

The above answers are good but with Express and node this will work fine.

Since express create the app for you, I'll skip that here.

var express = require('express')
  , fs = require('fs')
  , routes = require('./routes');

var privateKey = fs.readFileSync('cert/key.pem').toString();
var certificate = fs.readFileSync('cert/certificate.pem').toString();  

// To enable HTTPS
var app = module.exports = express.createServer({key: privateKey, cert: certificate});
22
votes

The minimal setup for an HTTPS server in Node.js would be something like this :

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

var httpsOptions = {
    key: fs.readFileSync('path/to/server-key.pem'),
    cert: fs.readFileSync('path/to/server-crt.pem')
};

var app = function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}

https.createServer(httpsOptions, app).listen(4433);

If you also want to support http requests, you need to make just this small modification :

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

var httpsOptions = {
    key: fs.readFileSync('path/to/server-key.pem'),
    cert: fs.readFileSync('path/to/server-crt.pem')
};

var app = function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}

http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);
18
votes

Update

Use Let's Encrypt via Greenlock.js

Original Post

I noticed that none of these answers show that adding a Intermediate Root CA to the chain, here are some zero-config examples to play with to see that:

Snippet:

var options = {
  // this is the private key only
  key: fs.readFileSync(path.join('certs', 'my-server.key.pem'))

// this must be the fullchain (cert + intermediates)
, cert: fs.readFileSync(path.join('certs', 'my-server.crt.pem'))

// this stuff is generally only for peer certificates
//, ca: [ fs.readFileSync(path.join('certs', 'my-root-ca.crt.pem'))]
//, requestCert: false
};

var server = https.createServer(options);
var app = require('./my-express-or-connect-app').create(server);
server.on('request', app);
server.listen(443, function () {
  console.log("Listening on " + server.address().address + ":" + server.address().port);
});

var insecureServer = http.createServer();
server.listen(80, function () {
  console.log("Listening on " + server.address().address + ":" + server.address().port);
});

This is one of those things that's often easier if you don't try to do it directly through connect or express, but let the native https module handle it and then use that to serve you connect / express app.

Also, if you use server.on('request', app) instead of passing the app when creating the server, it gives you the opportunity to pass the server instance to some initializer function that creates the connect / express app (if you want to do websockets over ssl on the same server, for example).

10
votes

To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following

Create an express app:

var express = require('express');
var app = express();

The app returned by express() is a JavaScript function. It can be be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app using the same code base.

You can do so as follows:

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();

var options = {
  key: fs.readFileSync('/path/to/key.pem'),
  cert: fs.readFileSync('/path/to/cert.pem')
};

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

For complete detail see the doc

0
votes

You can use also archive this with the Fastify framework:

const { readFileSync } = require('fs')
const Fastify = require('fastify')

const fastify = Fastify({
  https: {
    key: readFileSync('./test/asset/server.key'),
    cert: readFileSync('./test/asset/server.cert')
  },
  logger: { level: 'debug' }
})

fastify.listen(8080)

(and run openssl req -nodes -new -x509 -keyout server.key -out server.cert to create the files if you need to write tests)

0
votes

If you need it only locally for local development, I've created utility exactly for this task - https://github.com/pie6k/easy-https

import { createHttpsDevServer } from 'easy-https';

async function start() {
  const server = await createHttpsDevServer(
    async (req, res) => {
      res.statusCode = 200;
      res.write('ok');
      res.end();
    },
    {
      domain: 'my-app.dev',
      port: 3000,
      subdomains: ['test'], // will add support for test.my-app.dev
      openBrowser: true,
    },
  );
}

start();

It:

  • Will automatically add proper domain entries to /etc/hosts
  • Will ask you for admin password only if needed on first run / domain change
  • Will prepare https certificates for given domains
  • Will trust those certificates on your local machine
  • Will open the browser on start pointing to your local server https url
-4
votes
  1. Download rar file for openssl set up from here: https://indy.fulgan.com/SSL/openssl-0.9.8r-i386-win32-rev2.zip
  2. Just copy your folder in c drive.
  3. Create openssl.cnf file and download their content from : http://web.mit.edu/crypto/openssl.cnf openssl.cnf can be put any where but path shoud be correct when we give in command prompt.
  4. Open command propmt and set openssl.cnf path C:\set OPENSSL_CONF=d:/openssl.cnf 5.Run this in cmd : C:\openssl-0.9.8r-i386-win32-rev2>openssl.exe
  5. Then Run OpenSSL> genrsa -des3 -out server.enc.key 1024
  6. Then it will ask for pass phrases : enter 4 to 11 character as your password for certificate
  7. Then run this Openssl>req -new -key server.enc.key -out server.csr
  8. Then it will ask for some details like country code state name etc. fill it freely. 10 . Then Run Openssl > rsa -in server.enc.key -out server.key
  9. Run this OpenSSL> x509 -req -days 365 -in server.csr -signkey server.key -out server.crt then use previous code that are on stack overflow Thanks