A public key certificate is a way to send and verify the authenticity of a public key. Typically, a public key certificate will be signed by a trusted certificate authority (CA) that verifies the certificate’s legitimacy, also known as an issuer. Alternatively, a certificate may be self-signed, meaning it is signed by an individual instead of a CA.
In this tutorial, we’ll learn how to create a self-signed certificate. After that, we’ll learn how to configure our self-signed certificate to be trusted by applications on our system.
2. Creating a Self-Signed Certificate Using OpenSSL
We should begin by creating our private key and an associated self-signed certificate. On Linux, the most common method to do this is using openssl.
2.1. Creating Our Certificate’s Configuration File
The config file we use with the openssl command is where we’ll define our x509 extensions, distinguished name, and other general settings. Let’s take a look at an example configuration file that enables HTTPS on our localhost:
[ req ] prompt = no distinguished_name = distinguished_name x509_extensions = x509_extension [ distinguished_name ] CN = localhost [ x509_extension ] subjectAltName = DNS:localhost, IP:127.0.0.1 extendedKeyUsage = critical, serverAuth, clientAuth keyUsage = critical, digitalSignature, keyEncipherment
There are three sections in this configuration file: req, distinguished_name, and x509_extensions. The first section defined in our configuration file is the req section. This is where we define the other sections we’re using in our config. In addition, we set the prompt field to no, preventing prompting for distinguished name information when we create our certificate.
Let’s also have a look at the fields of the last two sections in our configuration file:
|distinguished_name||CN||(Common Name) Domain name applicable to certificate.|
|x509_extension||subjectAltName||Domain names and IP Addresses applicable to certificate.|
|x509_extension||keyUsage||The authorized uses of the certificate.|
|x509_extension||extendedKeyUsage||Purposes the certificate may be used for.|
The distinguished_name section sets the general information of our certificate. There are many more options we can set in this section, but openssl just requires that at least one field is defined in distinguished_name.
The x509_extension section is where we specify the usage, purpose, and domains of our certificate. We set extendedKeyUsage and keyUsage to critical to require that our certificate may only be used for the purposes expressly defined therein.
2.2. Creating Our Self-Signed Certificate and Private Key
Now that we’re finished creating our configuration file, we can create our certificate and private key:
$ openssl req -x509 -config config.cnf -newkey rsa:2048 -keyout mykey.pem -out mycert.crt -nodes ...
Two files should be created after the execution of this command, our self-signed certificate (mykey.pem) and our private key (mycert.crt).
In this example, we use openssl req to create our private key and digital certificate. Let’s review the options we used and their meanings:
|-x509||Creates a new self-signed certificate.|
|-config||Specifies a config file to use to make our certificate.|
|-newkey rsa:2048||Create a new 2048-bit RSA key to use with our digital certificate.|
|-keyout||Specifies the file name to use for our private key.|
|-out||Specifies the file name to use for our digital certificate.|
|-nodes||Creates the private key file without encryption (no password). For openssl version 3+ -noenc should be used instead.|
To output a list of all options for the openssl req command, we can use the -help flag.
3. Manually Trusting a Self-Signed Certificate
Now that we have our self-signed certificate, we’ll need to configure our system to trust it. This is handled differently depending on the distribution and application, but the methods used are similar.
3.1. Firefox and Chrome
Both Chrome and Firefox use network security services (NSS) to handle certificate trust. The only difference between the two is the path of their database.
To begin, we’ll first need to ensure we have the certutil command. Then, we can just run a simple script:
while read -r -d $'\0' i ; do certutil -d 'sql:'"$i" -A -t "C,," -n my_certificate -i mycert.crt done < <(find "$HOME" -type f -iregex '.*[/]cert[.]db' -printf '%h\0')
We locate all cert8.db and cert9.db files with find. These are the database files used by NSS to store certificates. We need to pass the parent directory of this file to certutil, so we use the -printf ‘%h\0’ option to print just the parent directory of the files found. Finally, we use process substitution to pass the outputted directories to our while loop.
To actually add our certificate to our database, we use the certutil command and specify the database with -d sql:directory. Next, we use the -A flag to tell our command we want to add a certificate to a database. The trust attributes of our certificate are disclosed using -t. In the case of a self-signed certificate, we use the trust attributes, “C,,”.
3.2. Debian-Based Distributions
Most other applications in Linux use the system’s trust store. However, the way that a system handles trusting certificates varies depending on which Linux distribution we’re on. Let’s begin by looking at the typical procedure used for Debian-based distributions:
$ cp mycert.crt /usr/local/share/ca-certificates $ update-ca-certificates
To add a certificate to the trusted list in a Debian-based distribution, we need to copy the certificate to /usr/local/share/ca-certificates. If we want to remove a certificate from the trusted list, we just have to take it out of this directory. To make these changes take effect we’ll need to run the update-ca-certificates command.
3.3. Arch and Fedora
Some distributions, such as Arch and Fedora, use p11-kit for their trust stores. In this case, we can trust our certificate using the trust command:
$ trust anchor --store mycert.crt $ update-ca-trust
In this example, we run trust anchor –store to store our certificate in the trust-source directory. Then we run update-ca-trust to make our changes take effect. To remove our certificate from the trusted list, we can run trust anchor –remove:
$ trust anchor --remove mycert.crt $ update-ca-trust
We can also remove our certificate from the trusted list by deleting the associated file in the ca-certificates/trust-source directory.
In this article, we learned how to make a self-signed certificate. After that, we saw how to add our certificate to the trusted list for Chrome and Firefox and then looked at system-wide solutions.