Translation of the articleHow to get HTTPS working on your local development environment in 5 minutes

Today, almost every website you visit is protected by HTTPS. If you haven’t done so yet, it’s time to do so. Securing your server with HTTPS means that you cannot send requests to this server from a non-HTTPS server. This is a problem for developers using local development environments that run under http://localhost.

During startup, we decided to use HTTPS to secure our AWS Elastic Load Balancer endpoints as part of our enhanced security. At first I had a problem with my local development environment being denied requests to the server.

After a quick Google search, I found a few articles that might be useful to me, like this one, this one, or this one, all with detailed instructions on how localhost implements HTTPS. But even if they followed these instructions, they failed. Chrome always throws me a NET::ERR_CERT_COMMON_NAME_INVALID.

The problem

All the steps in these articles are correct, but only when they were published, not now.

After a lot of Google searching, I discovered that my local certificate was rejected because Chrome no longer supports commonName matching in certificates, and in fact requires subjectAltName as of January 2017.

The solution

We will use OpenSSL to generate all the certificates.

  • Step 1: RootsSSLcertificate

The first step is to create a Secure Sockets Layer (SSL) certificate. This root certificate can then be used to sign any number of certificates that may be generated for a single domain. If you’re not familiar with the SSL ecosystem, this article from DNSimple does a good job of introducing Root SSL certificates.

Generate an RSA-2048 key and save it to a file rootca.key. This file will be used as the key to generate the root SSL certificate. You will be prompted for a password, which you will need to enter each time a certificate is generated using this particular key.

openssl genrsa -des3 -out rootCA.key 2048
Copy the code

You can use the key you generated to create a new root SSL certificate. Save it as rootca.pem. This certificate will be valid for 1,024 days. Feel free to change this to any number of days you want. During this process, you will also be prompted for additional optional information.

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
Copy the code

  • Step 2: Trust rootsSSLcertificate

Once this is done, you can use your newly created root SSL certificate. You need to tell your Mac to trust your root certificate, so that all individual certificates issued are also trusted.

On the Mac, open Keychain Access, go to the certificate list in System, and import the certificate rootca.pem by clicking the + button. Enter the password as prompted, and select Always Trust in the When Using this certificate: drop-down list

If you’ve done everything right, your keychain access should look like this.

  • Step 3: Domain SSL certificates

The root SSL certificate can now be used to issue certificates specifically for your local Localhost development environment.

Create a new oneOpenSSLConfiguration file,server.csr.cnfSo that these Settings can be imported when the certificate is created without having to enter them on the command line.

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=US
ST=RandomState
L=RandomCity
O=RandomOrganization
OU=RandomOrganizationUnit
[email protected]
CN = localhost
Copy the code

Create a v3.ext file to create an X509 V3 certificate. Notice that we specified the subjectAltName option.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
Copy the code

Create the certificate key tolocalhostUse the configuration Settings stored in itserver.csr.cnf. The key is stored inserver.key.

Openssl req -new -sha256 -nodes -out server. CSR -newkey rsa: 2048 -keyout server.key -config < (cat server.csr.cnf)Copy the code

The certificate signing request is issued through the root SSL certificate we created earlier, creating a domain name certificate for localhost. The output is a certificate file named server.crt.

openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext
Copy the code

Using your new SSL certificate you are now ready to localhost using HTTPS to protect your security. Move the files server.key and server.crt to an accessible location on the server and include them when starting the server.

Here’s what you do in an Express application written in Node.js. Make sure you only do this for your local environment. Do not use it in production.

Dev-server.js Hosted with ❤ by Github

var path = require('path')
var fs = require('fs')
var express = require('express')
var https = require('https')

var certOptions = {
  key: fs.readFileSync(path.resolve('build/cert/server.key')),
  cert: fs.readFileSync(path.resolve('build/cert/server.crt'))}var app = express()

var server = https.createServer(certOptions, app).listen(443)

Copy the code

I hope you find this tutorial useful. If you are not familiar with running the commands presented here, I have created a handy script that can be run quickly to generate certificates for you. More details can be found in the GitHub repository.

I love helping other Web developers. If you have any suggestions or feedback, please follow me on Twitter and let me know.