How To Write Your Own SSL Certificate in 15 minutes

SSL Certificate In 15 Minutes Main Logo

How To Write Your Own SSL Certificate in 15 minutes

All major sites have long switched to the https protocol. The trend continues, and many of our readers interested to secure their website to work on a secure protocol. And if a backend is developed for a mobile application, then https is required. For example, Apple requires that the server’s data exchange with the application is done via a secure protocol. This requirement was introduced from the end of 2016.

On production, there are no problems with certificates. Usually, the hosting provider provides a convenient interface for connecting the certificate. Issuing a certificate is also not a difficult matter. But while working on the project, each developer should take care of the certificate himself.

  • In this article, I’ll show you how to release a self-signed SSL certificate and get the browser to trust it.

To issue a certificate for your local domain, you will need a root certificate. On its basis, all other certificates will be issued. Yes, for each new top-level domain, you need to issue your own certificate.

Notes: Someone might even say that It’s easier to buy any cheap Domain Name and get a certificate from Letsencrypt for free than to deal with this nonsense. But this article was specifically written for those developers how are interested in creating their own product and loves to experiment with a couple lines of code.

Getting a root certificate is quite easy.SmartSpate

First, form the private key:


openssl genrsa -out rootCA.key 2048

Then the certificate itself:


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

It will be necessary to enter the country, city, company, etc.

As a result, we get two files:

  • rootCA.key
  • rootCA.pem

We pass to the main thing, the release of a self-signed certificate. As with the root, these are two teams. But the parameters for the teams will be much larger. And we need an auxiliary configuration file. Therefore, we will write all this in the form of bash script create_certificate_for_domain.sh

The first parameter is mandatory, we will derive a small instruction for the user.


if [ -z "$1" ]
then
echo "Please supply a subdomain to create a certificate for";
echo "e.g. mysite.localhost"
exit;
fi

Create a new private key if it does not exist or we will use the existing one:


if [ -f device.key ]; then
KEY_OPT="-key"
else
KEY_OPT="-keyout"
fi

Here, we are going to ask the user for the domain name. Add the ability to specify a “common name” (it is used to form a certificate):


DOMAIN=$1
COMMON_NAME=${2:-$1}

In order not to answer questions in interactive mode, we will form a string with answers. And we set the validity period for the certificate:


SUBJECT="/C=CA/ST=None/L=NB/O=None/CN=$COMMON_NAME"
NUM_OF_DAYS=999

The SUBJECT variable lists all the same questions that were asked when creating a root certificate (country, city, company, etc). All the value except CN can be changed at your discretion.

Now, creating a CSR file (Certificate Signing Request) based on the key. More information about the certificate request file can be found in this article.


openssl req -new -newkey rsa:2048 -sha256 -nodes $KEY_OPT device.key -subj "$SUBJECT" -out device.csr

Form the certificate file. To do this, we need an auxiliary file with the settings. In this file, we will write the domains for which the certificate will be valid and some other settings. Call it v3.ext. Pay your attention that this is a separate file, not part of the bash script.


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

[alt_names]
DNS.1 = %%DOMAIN%%
DNS.2 = *.%%DOMAIN%%

Yes, you are right, our certificate will be valid for the main domain, as well as for all subdomains. Save the above lines to the file v3.ext

We return to our bash script. On the basis of the auxiliary file v3.ext we create a temporary file with the indication of our domain:


cat v3.ext | sed s/%%DOMAIN%%/$COMMON_NAME/g > /tmp/__v3.ext

Issue the certificate:


openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days $NUM_OF_DAYS -sha256 -extfile /tmp/__v3.ext

Rename the certificate and delete the temporary file:


mv device.csr $DOMAIN.csr
cp device.crt $DOMAIN.crt

# remove temp file
rm -f device.crt;

The script is ready. Now, time to run it:


./create_certificate_for_domain.sh mysite.localhost

We get two files:

  • mysite.localhost.crt
  • devise.key

Now, you need to specify the web server paths to these files. For nginx, this would look like this:

SSL Certificate In 15 Minutes Photo 1

Launch the browser, open https: //mysite.localhost and see:

SSL Certificate In 15 Minutes Photo 2

The browser does not trust this certificate. How to be?

It is necessary to note the certificate issued by us as Trusted. On Linux (Ubuntu and, probably, other Debian-based distributions) this can be done through the browser itself. In Mac OS X, this can be done through the Keychain Access application. Run the application and drag the file mysite.localhost.crt to the window. Then open the added file and select Always Trust:

SSL Certificate In 15 Minutes Photo 3

We update the page in the browser and:

SSL Certificate In 15 Minutes Photo 4

Success! The browser trusts our certificate.

A certificate can be shared with other developers so that they add it to themselves. And if you use Docker, then the certificate can be saved there.