Create Certificates for Local HTTPS Development

Create Certificates for Local HTTPS Development

During development we sometimes need to generate SSL certificates for our application. In this article we’ll generate a key and a root certificate to use in generating other certificates. This can be helpful if you run many applications during development that need ssl certificates. We generate a root certificate so we can trust the root certificate once, and all our generated certificates will be honored by our operating system.

Development Only

This is meant for development only. It is important to keep the root certificate secure nonetheless.

I like bash. I have used bash for a long time, so we’ll be using that here.

Generate Certificate Authority

First, we generate our private key. All the certificates will be signed using this one key.

Terminal window
openssl genrsa -aes256 -out myca.key 4096

Now we generate a root certificate.

This is the certificate that we can add to our system later. We only need to add this one certificate to the browser, or phone, and we won’t continue to get that self-signed certificate warning. Obviously, self-signed certificates are not suitable for production use. This is for development only.

Terminal window
openssl req -x509 -new -sha512 -nodes -days 36500 \
-key myca.key \
-out myca.crt \
-subj "/C=US/ST=Earth/L=Home/O=myca-Dev/OU=Development/CN=myca"

Add to Your OS keychain/store: I use a mac, so I had to add the cert to my keychain.

Terminal window
sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" myca.crt

Creating CA-Signed Certificates for Your Dev Sites

Set the domain in bash: Makes it easier to work with later.

Terminal window
export DOMAIN=mysite.com
export ROOT_CERT=myca.crt
export CA_KEY=myca.key

Create a Subject Alternative Names (SAN) configuration file:

Use the below as a template and save as san.cnf. This configuration will be used to generate a certificate for mysite, *.mysite subdomains, and localhost.

Terminal window
cat > "san.cnf" <
<-EOF
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
# The extensions to add to a certificate request - see [ v3_req ]
req_extensions = v3_req
[ req_distinguished_name ]
countryName= US
stateOrProvinceName= Earth
localityName= Home
organizationName= Development
organizationalUnitName= Development
commonName= $DOMAIN
emailAddress= [email protected]
[ req_attributes ]
# None
[ v3_req ]
# X509v3 extensions to add to a certificate request
# See x509v3_config
# What the key can/cannot be used for:
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth,serverAuth
# The subjectAltName is where you give the names of extra web sites.
# You may have more than one of these, so put in the section [ alt_names ]
# If you do not have any extra names, comment the next line out.
subjectAltName = @alt_names
# List of all the other DNS names that the certificate should work for.
# alt_names is a name of my own invention
[ alt_names ]
DNS.1 = $DOMAIN
DNS.2 = *.$DOMAIN
DNS.3 = localhost
EOF

Create a private key for the certificate: This is a different key from the Certificate Authority.

Terminal window
openssl genrsa -out "$DOMAIN.key" 4096

Create a Certificate Signing Request (CSR):

Terminal window
openssl req -new -key "$DOMAIN.key" -config "san.cnf" -out "$DOMAIN.csr"

Create that X.509v3 extensions file (${DOMAIN}.ext):

Terminal window
cat > "$DOMAIN.ext" <
<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = $DOMAIN
DNS.2 = *.$DOMAIN
DNS.3 = localhost
EOF

Sign your certificate:

Terminal window
openssl x509 -req -sha512 -CAcreateserial -days 36500 \
-extfile "$DOMAIN.ext" \
-CA "$ROOT_CERT" \
-CAkey "$CA_KEY" \
-in "$DOMAIN.csr" \
-out "$DOMAIN.crt"

Generate a PEM formatted certificate:

This might prove useful sometimes, though it’s optional.

Terminal window
openssl x509 -inform PEM -in "$DOMAIN.crt" -out "$DOMAIN.cert"

Script to generate a certificate

You can check out the set of scripts that make this much easier at https://gitlab.com/anton.kronaj/certgen

Cheers,
Anton

Resources

Originally published on Medium: Create Certificates for Local HTTPS Development

Share this post