Create Self-signed certificates with OpenSSL
Tags: tutorial, security, webdev, beginners
Published: 2023-02-04 17:11:06

In this guide, I give a step-by-step guide on how to create a self-signed CA and a certificate signed by using the OpenSSL command. Once you know how it works, you can create your own scripts to automate the process.

The mentioned OpenSSL command is a utility that lets you create and inspect certificates.

## What is a Self Signed Certificate?

All computers come with a bunch of pre-installed CA. When you go to https://google.com you can see a lock to the left of the URL. This means you trust the site certificates. In other words, your computer trusts the CA of the Google certificate.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8gmvy9p07xo2xpo8cf6.png)

With a self-signed certificate, this doesn't happen. The browser throws a warning indicating there's a security risk because you don't trust the certificate. You don't trust the CA that signed that certificate.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zc0f8fydomacrdw58cn8.png)

If you don't want to see this warning, you have to install the CA. That way you are telling the browser to trust the certificates signed by that CA.

### Benefits

1. You don't need to pay to have a CA
2. If you need to establish secure connections with TLS but can't use third parties to sign your certificates

### Drawbacks

1. You'll need to trust the CA in the browser or application manually
2. You have to be careful about where you save the private keys

## Create Certificate Authority

First, we need to create our own root CA that will sign our certificates. If we trust in this CA, we trust in the certificates.

### 1. Create the Private Key

Execute the following `openssl` command to generate the private key.

```
openssl genrsa -aes128 \
      -out rootCA.key \
      -passout pass:ca_12345 4096
```

- **Encryption:** `-aes128`. The [allowed options](https://www.openssl.org/docs/man1.1.1/man1/openssl-genrsa.html) are: `-aes128, -aes192, -aes256, -aria128, -aria192, -aria256, -camellia128, -camellia192, -camellia256, -des, -des3, -idea`. Some, such as `-des` and `-des3` are not considered secure anymore.
- **Private Key Size:** 4096. The minimum size is 2048. I always use 4096 for the CA, as seen in the Google Root CA.  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/11zp6aahjqjqf0xoz7zl.png)

### 2. Create the Certificate

We will create the self-signed public certificate using the private key. 

```
openssl req -new -x509 \
      -days 3650 -sha256 \
      -key rootCA.key \
      -passin pass:ca_12345 -out rootCA.crt
```

- **Signature Hash algorithm:** `-sha256`
You can execute `openssl list --digest-commands` to see the available ones. Google uses `sha384`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sa71oufbucjvs8rcv24e.png)

- **Days until it's not valid:** 3650

To view the certificate you've just created, you can use the following command:

`openssl x509 -in rootCA.crt -noout -text`

## Create Self-Signed Certificates

Follow the following steps below to create self-signed certificates. These certificates will be signed by the root CA we created in the previous step.

### 1. Create the Private Key

As we did with the root CA, we need to create a Private key. This time we'll use 2048 as the size. In case of doubt, you can explore big companies' certificates to see how they do it.

```
openssl genrsa -aes128 \
      -out serverCert.key \
      -passout pass:server_12345 2048
```

### 2. Create Certificate Configuration

We will create a `serverCert.conf` to have all the certificate data in one place.

```console
cat > csr.conf <<EOF
[ req ]
prompt = no
distinguished_name = requested_distinguished_name
req_extensions = requested_extensions
x509_extensions = requested_extensions

[ requested_distinguished_name ]
countryName = ES
stateOrProvinceName = Madrid
localityName = Madrid
organizationName = Mock Organization
organizationalUnitName = Mock Organization Devops
commonName = mockorg.com
emailAddress = devops@mockorg.com

[ requested_extensions ]
basicConstraints = CA:FALSE
subjectAltName = @list_of_alternative_names

[ list_of_alternative_names ]
DNS.1 = mockorg.com
DNS.2 = www.mockorg.com
DNS.3 = devops.mockorg.com

EOF
```

### 3. Generate a CSR (Certificate Signing Request)

The next step is to generate the file `serverCert.csr`.

```
openssl req -new -sha256 \
      -config serverCert.conf \
      -key serverCert.key -passin pass:server_12345 \
      -out serverCert.csr
```

### 4. Generate Certificate
The last step is to generate the certificate using the just-created CSR.

```
openssl x509 -req -days 1460 -sha256 -in serverCert.csr \
	-CA rootCA.crt -CAkey rootCA.key -CAcreateserial \
	-out serverCert.crt -passin pass:ca_12345 \
	-extensions requested_extensions -extfile serverCert.conf
```

To view the certificate you've just created, you can use the following command:

`openssl x509 -in serverCert.crt -noout -text`