JRehkemper.de

Generate Self-Signed Certificates with OpenSSL

Certificates are a fundamental part of modern encryption and is used in protocols like https. For a certificate to be valid, it has to be trusted. Usually your system will trust a certificate, if it trusts the authority who signed the certificate.

Certificate Authorities

Usually you will have a Certificate Authority (CA) that will sign all your certificates. If you propagate this CA to your clients, your clients will trust all certificates signed by your CA. This will prevent the “This connection is not save.” warning in your Browser.
If you just need a quick and dirty certificate to use ssl on a webserver, you might not want to setup a CA for that. But keep in mind this certificate will be seen as untrusted by your clients.

Create a Certificate Authority

First we need a private key for our CA to sign requests. Keep this key save. It is compromised everyone can sign certificates in you name.

$ openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt

Generate Certificate with CA

If you use a CA you will create a Certificate-Signing-Request or CSR. This request will then be signed by your CA to become a valid Certificate.

To create the CSR do as follows.

$ openssl req -newkey rsa:2048 -keyout domain.key -out domain.csr

Then sign it with your rootCA.

$ openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in domain.csr -out domain.crt -days 365 -CAcreateserial -extfile domain.ext

Generate Certificate without CA

If you want to generate a certificate you can either answer the required information interactively or by creating a configuration file. The interactive approach is faster, while the configuration file is more explicit and gives you some more options.
The most important options are the CommonName and the subjectAltName or alternativeNames. These should contain all the hostnames and domains that you will use this certificate for. The rest of the information will be embedded into the certificate as well, but it is relevant for security. They are only for User-Information.

Interactive configuration

$ openssl req -x509 -days 365 -newkey rsa:2048 -nodes -keyout mykey.key -out mycert.crt

req -x509: Generate a Certificate and not a CSR
-days 365: The certificate will be valid for 365 days
-nekey rsa:2048 -nodes: Create a new rsa key for the certificate with a length of 2048 Bit. Do not use a passphrase (-nodes).
-keyout mykey.key: save the key as mykey.key
-out mycert.crt: save the certificate as mycert.crt.

Configuration File

A configuration file for your certificate could look like this and may be called whatever you want.

[req]
default_bits = 2048
encrypt_key = no
default_keyfile = mykey.key
distinguished_name = req_distinguished_name
x509_extensions = x509_extensions

[req_distinguished_name]
# Enter these options
C = US
ST = WA
L = Seattle
O = MyCompany
OU = MyDivision
CN = *.domain.test

[x509_extensions]
subjectAltName = @alternate_names

[alternate_names]
# Extra domain names to associate with our cert
DNS.1 = *.domain.test
DNS.2 = localhost
DNS.3 = 127.0.0.1
DNS.4 = mail.domain.test

Now we can use these configuration to create a certificate.

$ openssl req -x509 -days 365 -newkey rsa:2048 -config myconfig.cnf -keyout mykey.key -out mycert.crt

View Certificate

You can use openssl to display all the information embedded in your certificate.

For CertificateSigningRequests its

$ openssl req -text -noout -verify -in mycsr.csr

For Certificates its

$ openssl x509 -text -noout -in mycert.crt

Get a public Certificate

If you need a certificate for a public-facing website, you probably don’t want to use self-signed Certificates. Otherwise all your user will be warned, that their connection is not secure. And most of them will turn around on the spot.

In the past you had to buy Certificates from big CAs for quite a lot of money.
Luckily that is not necessarily the case anymore. For most of us Let’s Encrypt is a great solution. The offer the possibility to sign valid certificates for free. The only requirement is, that your server needs to be reachable through the internet. That’s because Let’s Encrypt will give your server a so called challenge. This is done to proof that you are the owner of the server, you want a certificate for. Otherwise you could create a certificate for google.com and that could be a great option for scamming and man-in-the-middle attacks.

profile picture of the author

Jannik Rehkemper

I'm an professional Linux Administrator and Hobby Programmer. My training as an IT-Professional started in 2019 and ended in 2022. Since 2023 I'm working as an Linux Administrator.