How to generate a self-signed SSL certificate on Linux

SSL is a protocol used to encrypt and authenticate data on networks, typically between a server and a client. The SSL protocol, and its successor, TLS, use asymmetric encryption which is based on two keys: a private and a public one. An SSL certificate provides an encrypted connection and creates an environment of trust, since it certifies the website we are connecting to is effectively what we intend, and no malicious party is trying to impersonate it. Valid SSL certificates are released by a CA (Certificate Authority), but they can also be self-generated. Self signed SSL certificates, while still providing encryption, don’t provide any trust, since the owner and the issuer are the same entity/person. Nonetheless, they can be useful in certain situations: for testing or internal usage, for example.In this tutorial we see how to generate a self-signed SSL certificate and key pair using the OpenSSL toolkit on Linux, how to read the content of a certificate, and how to extract the public key from it.

In this tutorial you will learn:

  • How to generate a self-signed SSL certificate and key pair on Linux
  • How to read the content of an SSL certificate
  • How to extract the public key from a certificate
How to generate a self-signed SSL certificate on Linux
How to generate a self-signed SSL certificate on Linux

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software OpenSSL toolkit
Other None
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installing the OpenSSL toolkit

The OpenSSL toolkit is available in the official repositories of the most used Linux distributions. It contains a set of utilities and libraries which provide support for various types of protocols and algorithms. There are very high changes the toolkit is already installed on your system, as a dependency of its core packages; however, to install it explicitly, we can just use the package manager of our distribution of choice. On Fedora and other distribution which are part of the Red Hat family, we use dnf:

$ sudo dnf install openssl

On Debian, Ubuntu and their derivatives, instead, we can use the apt wrapper:

$ sudo apt install openssl

If Archlinux is our daily driver, we can install the OpenSSL toolkit using the pacman package manager. The package is maintained in the “core” repository:

$ sudo pacman -Sy openssl

Once the toolkit is installed we can see how to use it to generate a self-signed certificate.

Generating a self-signed certificate

In order to generate a self-signed certificate, we can make use of one of the many utilities included in the OpenSSL toolkit: req. This tool is well described in the following way:

The req command primarily creates and processes certificate requests in PKCS#10 format. It can
additionally create self signed certificates for use as root CAs for example.



To generate our certificate, together with a private key, we need to run req with the -newkey option. Let’s see an example of the command. We will discuss it later:

$ openssl req -newkey rsa:4096  -x509  -sha512  -days 365 -nodes -out certificate.pem -keyout privatekey.pem

Let’s analyze the various options we used in the example above. First of all we invoked “req” with the -newkey option: it is used to create a new certificate request and a private key. It takes one argument which we can use to specify the type of key we want to generate, together with its size. In the example we used: rsa:4096, so to create an RSA key of 4096 bits. If we omit the key size, the default one is used (2048).

The second option we used is -x509. What this option does is simply modifying the behavior of the program so that a self-signed certificate is created instead of a certificate request. What is the difference between the two? A certificate request is created on the server where the certificate needs to be installed and sent to a Certificate Authority, which issues the certificate. A self-signed certificate instead, as we already mentioned, is owned and provided by the same person or entity. No Certificate Authority is involved in the process: this is why this type of certificate provides no trust.

With -sha512 we specified the message digest to sign the request/certificate. The default digest is, again, specified in the OpenSSL configuration file, under the default_md key, and is sha256.  To get the list of all available digest, we can run:

$ openssl list --digest-commands

We should obtain a result similar to the following:

blake2b512        blake2s256        gost              md2               
md4               md5               rmd160            sha1              
sha224            sha256            sha3-224          sha3-256          
sha3-384          sha3-512          sha384            sha512            
sha512-224        sha512-256        shake128          shake256          
sm3               

Since we are generating a self-signed certificate, we can decide by ourselves for how long it will be valid. The validity period is expressed in days (30 is the default); the number of days are passed as argument to the -days option. In this case, we made our certificate value for a whole year.

With the -nodes option we specified that we don’t want to encrypt the generated private key. Encrypting the private key is without doubts useful: this can be intended as a security measure in case someone stoles it, since to use it, a passphrase should be provided. Just as an example, if we use a private key with Apache, we must provide the passphrase to decrypt it each time we restart the daemon. In this case, since we are generating a self sign certificate, which we will use for testing, therefore we can avoid encrypting the private key.

Finally, we used the -out and -keyout options to specify the filenames to write the certificate and the key to, respectively. In this case the certificate will be saved into the certificate.pem file, and the private key into the privatekey.pem file. Why did we use “.pem” as the file names suffix? This is because both the certificate and key will be created in PEM format. PEM stands for “Privacy Enhanced Mail”: it is basically a container which includes base64 formatted data.

Providing the certificate information

Once we run the command to generate the certificate, we will be prompted to provide a series of information. Among the others:

  1. Two letters representing the Country Name (e.g US)
  2. The full State or Province Name (e.g. California)
  3. The City name (e.g Los Angeles)
  4. The Organization or company name (The legal name of the company)
  5. The fully qualified name of the server
Generating a RSA private key
.............................................++++
...........................++++
writing new private key to 'privatekey.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:California
Locality Name (eg, city) [Default City]:Los Angeles
Organization Name (eg, company) [Default Company Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.fqdn.com
Email Address []:

Reading the content of the certificate

At the end of the process we should find the two created files (certificate.pem and privatekey.pem) in our current working directory. If we take a look at our certificate file we should find a content similar to the following:

-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIUYqXQl7Y5G6BAXpQ32GWfekpTEJcwDQYJKoZIhvcNAQEN
BQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAcM
C0xvcyBBbmdlbGVzMRUwEwYDVQQDDAx3d3cuZnFkbi5jb20wHhcNMjIwMzIwMjI0
NTU4WhcNMjMwMzIwMjI0NTU4WjBPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
aWZvcm5pYTEUMBIGA1UEBwwLTG9zIEFuZ2VsZXMxFTATBgNVBAMMDHd3dy5mcWRu
LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALHf3gnGCATAUEKc
xgq3mmwM+wI9HV3SaYEnHgNJnt47FgFHcLWmzMRARrx1ofrwWSYUCGNDidit6FHv
fHDyVoH344G8tuyU5YhzddmmphoGpU7jdwbQvtSqcJxOU84KSmwoMp/sIb+iNfSA
rcNj1mTMHJJmePwCloDT2/7tuMvBlhfG5JHk5mSwi2GpSi06VqkzKeRBzaJTKEVq
vUJNOcBJBCJPhj+I32J3SeJ6YnCfvLyaBzVBR0T+2umGXDTU0KwSnoCg3Swslfma
GKDNLzvUerqwxEEUjaKjzdtzclvVJ86xVGI1TiVPdngullHCBdys5PxXabxhv1mF
FRgxCXjyctVeEcTx+SIDoxMWVTZFXFbaGUbeXFYEXbm0dzYOj0Y+rbIxvBVGfLDG
qngUuIOE3iiaOA/h/V0MuIhFVXg0tO4ZIsN5sZAMpGuLduB5W2soNpb7uRVneEyP
VIYwzYT8i4YJMVXCMwQKHQFQbeU2QKTsx0aXnR7O84CUQxCah86FJpzNP5jMjTht
82X08rKGBp5G85hyUQEyvZrtQ9etFHDVdDvfuuFFQf0vXwDUpS7WHOOcK1+M0ztr
lxk/vg4qazw7vwXSRD93a1VgnsGAXV8oxKuzUzUCj96JJvjdnd56h3B9ERShEpZx
Ua1lgB8sTDG8l3kTpggsfXWHgLTRAgMBAAGjUzBRMB0GA1UdDgQWBBSnylKfTIQJ
PNbq+z50Ao0HfrpfMjAfBgNVHSMEGDAWgBSnylKfTIQJPNbq+z50Ao0HfrpfMjAP
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4ICAQBDISi+LunywZWapJFc
XbPll/BKbsJNX+4gmMOysFr0QRtDfrXGKN57DlZvfYlkNeBdXi6urGfWuuERbmqo
IN2KmYbCTCG5RhfiVvS9MvbQOtItq+tJCIVD2YznblAniU2qy3tquGVLGRSR2SuB
X/r8a6NGZ8SzxpeUgQEKYStiIVjkAUrLzn0UXy7ul7pTghy5w4AgiC0AwecnUWwl
Dyb+TXadAD0PfHvHMJvMTlfFtVGJgDFPPPAocQ1BHmzxsY01QcXnOfUXGwoldrp5
H5Yf+kbxru6TMPoC8Q0oZqPXX5k4SmOP3npaFQ3q6Zti6Z0EXY1Tq9h0pBTJMXzK
B4RX7owrX3k7H2DPZjColyFzjmmdTT75y9CGrDwoKk6RQFDO5/aSfkE3y+KFbQq/
rib/BymCzoYl/4E5LA7SStBk0pTv0qRJEqOhzNdOqkq+xWAEC4JN8a63MY1Fxaii
cDgEeYLtdSpfEyB2AsmYDa+hF9lmYP3pcInCsU3iSuYpn8g09iHtCWAvyvcO2tyP
JT+Gi6h38jAIAziUI3kXVTbc9tvVfDRlF4mK66z1Iz7loMP4TMSObW35mf200Zvt
HqbrhlF8KWMY/IxCM0LNkxQXEIoW3yHm3G3OHoV184XTyW0CKFK18dC8SuYc24cX
kLAgdGVMwED+WtoF6hPKfznmIA==
-----END CERTIFICATE-----



As we already said, the certificate is PEM-formatted, therefore to read its content, we can issue the following command:

$ openssl x509 -noout -in certificate.pem -text

The x509 utility is used to display and sign certificates. In this case we invoked it with the -noout option to avoid the encoded version of the certificate to be included in the output, -in to specify the file containing the certificate to be used as input (certificate.pem, in this case) and -text to print the output of the certificate in text form. In this case we just wanted to visualize the certificate content on the standard output; to save it to a file we could have used the -out option and provided the destination filename as its argument, or simply use shell redirection. Here is the output of the command:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0f:d2:5a:6c:99:74:37:2e:4b:3a:86:a3:d3:61:95:6a:03:85:04:71
        Signature Algorithm: sha512WithRSAEncryption
        Issuer: C = US, ST = California, L = Los Angeles, CN = www.fqdn.com
        Validity
            Not Before: Mar 21 11:03:48 2022 GMT
            Not After : Mar 21 11:03:48 2023 GMT
        Subject: C = US, ST = California, L = Los Angeles, CN = www.fqdn.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (4096 bit)
                Modulus:
                    00:b9:6a:fa:50:18:bb:3d:26:80:ef:a4:08:1d:8c:
                    11:14:c5:5e:81:73:d3:4d:32:b2:86:9a:c2:04:53:
                    44:74:b8:34:ca:99:42:71:01:30:ae:f3:ef:59:83:
                    fb:bc:8d:e6:ca:b4:7b:6c:82:fe:f5:19:0a:76:26:
                    d6:de:9e:33:62:52:74:a9:63:f9:09:f8:41:4f:9c:
                    68:0b:23:4c:62:61:ad:59:8e:f5:bc:e8:42:b3:1a:
                    3d:4e:19:6b:4d:20:b3:42:a5:ae:a1:6f:14:7e:c8:
                    d5:e9:1d:ac:6a:26:5d:ef:40:58:55:b7:21:a6:0d:
                    fb:94:76:a9:95:67:59:c4:2e:5a:42:0f:25:fa:b3:
                    c9:67:38:f2:2f:3b:84:62:d0:6c:1f:b1:ea:58:8b:
                    12:35:13:45:47:01:d9:66:04:b0:ed:39:cd:e7:ed:
                    17:a1:ea:bd:27:89:e7:b9:26:96:82:d1:d3:d8:75:
                    82:f6:f6:07:31:6b:d7:7a:59:87:24:61:0a:3b:29:
                    97:49:43:ef:26:a1:9e:98:f2:ff:ea:49:01:a0:bf:
                    9b:45:69:b1:b6:c2:2e:de:e5:e0:43:09:a3:82:46:
                    cf:64:84:d2:eb:dd:7d:08:92:f3:89:e3:51:97:25:
                    23:be:62:c6:f8:ff:b4:b5:ae:78:a9:ff:81:a8:76:
                    7b:79:c3:05:55:f0:ce:11:b4:38:00:ef:1f:bd:58:
                    bd:cf:2e:74:ce:30:38:94:d4:64:ab:fc:a9:98:24:
                    18:dc:e1:10:f8:67:b5:ef:b8:ec:81:60:5d:7a:f3:
                    1e:01:fe:87:2b:55:71:01:0c:7f:fc:4b:9a:3a:33:
                    3e:c8:28:33:e6:ad:18:ef:1d:98:33:1e:89:fb:4c:
                    0b:e8:d2:5a:9d:53:70:2a:12:29:ed:45:79:89:55:
                    30:4a:f6:5f:41:98:8d:d6:37:d5:a0:02:8a:75:3e:
                    07:c4:67:45:56:85:c9:8e:5f:25:fb:77:0c:48:94:
                    29:07:95:f0:07:39:fc:cd:09:02:9b:07:3d:11:8b:
                    62:4e:e8:5e:fc:c6:a0:41:aa:20:a1:c9:44:63:eb:
                    fd:db:4b:7c:62:1b:b1:46:93:08:37:30:d9:11:84:
                    0e:ad:97:0b:20:29:41:ba:89:b6:36:84:7d:b6:59:
                    47:06:86:5a:d6:04:48:b6:87:c8:9c:c7:c3:02:02:
                    6e:51:ea:11:46:db:d5:b1:9e:e9:75:46:26:5f:9f:
                    15:92:bc:9c:4b:e2:4d:1b:bc:d5:1b:2e:b0:56:71:
                    fb:4a:20:91:11:8b:31:ae:55:83:e7:e5:96:61:9f:
                    4d:46:08:02:d3:20:b6:b2:f2:ad:72:78:73:27:a8:
                    36:92:6f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                62:B1:F4:A8:E1:76:4E:DA:23:67:2D:4B:48:BC:DE:63:4D:7A:15:CB
            X509v3 Authority Key Identifier: 
                keyid:62:B1:F4:A8:E1:76:4E:DA:23:67:2D:4B:48:BC:DE:63:4D:7A:15:CB

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha512WithRSAEncryption
         1d:67:0f:7e:5e:0f:13:7b:ce:80:cd:18:d7:01:ce:65:b7:b0:
         c7:6f:21:1c:41:1c:8b:d8:d1:53:1d:2b:4c:57:2a:60:30:62:
         d9:d1:1f:6d:ff:8e:56:d0:8b:0b:b1:83:ee:a9:b4:d6:84:cd:
         ca:c6:9c:f8:84:7c:47:7b:c6:08:6d:b2:20:9b:88:02:4b:5c:
         30:32:17:2d:37:a6:a3:de:24:14:fb:8c:d1:82:1d:bc:4e:2e:
         52:a4:87:8d:98:fc:4b:b1:e2:ac:2a:ed:f9:e9:21:36:bc:a0:
         90:f5:a3:f7:f5:5a:e7:5e:aa:a7:58:b6:97:b5:b0:73:f5:03:
         14:91:b1:fe:41:49:05:17:e4:fb:0d:be:07:38:86:9d:b4:5a:
         02:c7:91:e9:c0:c1:53:59:e5:3f:60:2c:cb:fe:15:94:30:67:
         f2:a9:1a:d9:a1:71:49:43:a9:45:cb:97:14:7f:e7:6a:9d:19:
         41:95:db:01:d9:ba:fc:5f:51:43:5b:cd:14:ff:4b:b0:63:7c:
         6b:76:54:86:b9:c6:a2:92:16:7c:22:09:eb:b6:4c:4a:85:40:
         e8:9f:fb:0a:40:ff:2d:c6:75:06:f9:67:ba:2e:63:4e:25:0e:
         bb:0d:e0:d4:05:9c:ce:c5:b4:36:19:58:db:87:f6:af:1c:4d:
         45:2b:de:ec:f2:9a:4a:e2:0e:63:5f:bb:fa:15:20:35:10:93:
         ce:23:35:33:16:f8:61:c0:6e:48:12:55:29:d2:5a:41:d1:9a:
         47:ef:d9:fd:54:91:15:a0:4b:83:b2:f6:78:1d:98:e5:71:03:
         2a:4b:eb:db:49:78:61:85:16:71:ea:a6:ed:8e:64:98:00:e0:
         73:9a:66:4b:4c:30:b7:d3:a7:0c:bb:af:09:cc:5c:c1:7a:ef:
         9c:42:19:1b:95:e4:25:37:ba:cf:db:74:1f:cd:a3:a9:84:11:
         39:27:62:59:60:7e:b4:82:e6:a0:33:bd:e9:32:6a:86:61:86:
         cf:dc:1e:f0:93:b7:42:7d:92:5d:39:df:c2:60:1b:5a:b4:0d:
         5e:20:92:7a:d4:09:4f:2e:87:81:34:bb:aa:75:97:b1:f8:23:
         bd:ff:63:12:fa:d2:3b:8b:8c:74:7c:1b:16:2b:0a:5b:94:69:
         22:58:45:d2:0f:75:16:26:60:d9:81:7b:e9:83:79:26:b0:c0:
         32:ca:46:80:07:eb:df:8e:00:c8:fa:17:a5:e1:e2:24:cc:2c:
         a6:13:a2:0d:35:d6:5a:1a:d1:5e:a2:d7:83:69:32:73:af:77:
         ed:6a:13:7b:60:d2:2c:78:f2:0d:4b:04:ec:c6:57:38:50:ee:
         a4:ab:c0:b0:24:4b:01:70

Extracting the public key from a certificate

As we saw, SSL/TLS is based on asymmetric encryption, and the use of a private and a public key. The private key must remain secure on the server, while the public key is sent to the client together with the certificate. How can we extract the public key included in it? Well, it is a very simple operation. To accomplish this task we must use again the -x509 command. To extract the public key from the certificate we generated in this tutorial, we would run:

$ openssl x509 -pubkey -noout -in certificate.pem



We invoked x509, this time using the -pubkey option, which makes so that the certificate public key is printed in PEM format:

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuWr6UBi7PSaA76QIHYwR
FMVegXPTTTKyhprCBFNEdLg0yplCcQEwrvPvWYP7vI3myrR7bIL+9RkKdibW3p4z
YlJ0qWP5CfhBT5xoCyNMYmGtWY71vOhCsxo9ThlrTSCzQqWuoW8UfsjV6R2saiZd
70BYVbchpg37lHaplWdZxC5aQg8l+rPJZzjyLzuEYtBsH7HqWIsSNRNFRwHZZgSw
7TnN5+0Xoeq9J4nnuSaWgtHT2HWC9vYHMWvXelmHJGEKOymXSUPvJqGemPL/6kkB
oL+bRWmxtsIu3uXgQwmjgkbPZITS6919CJLzieNRlyUjvmLG+P+0ta54qf+BqHZ7
ecMFVfDOEbQ4AO8fvVi9zy50zjA4lNRkq/ypmCQY3OEQ+Ge177jsgWBdevMeAf6H
K1VxAQx//EuaOjM+yCgz5q0Y7x2YMx6J+0wL6NJanVNwKhIp7UV5iVUwSvZfQZiN
1jfVoAKKdT4HxGdFVoXJjl8l+3cMSJQpB5XwBzn8zQkCmwc9EYtiTuhe/MagQaog
oclEY+v920t8YhuxRpMINzDZEYQOrZcLIClBuom2NoR9tllHBoZa1gRItofInMfD
AgJuUeoRRtvVsZ7pdUYmX58VkrycS+JNG7zVGy6wVnH7SiCREYsxrlWD5+WWYZ9N
RggC0yC2svKtcnhzJ6g2km8CAwEAAQ==
-----END PUBLIC KEY-----

Closing thoughts

In this tutorial we learned how to generate a self-signed SSL certificate using the OpenSSL toolkit and the “req” command. We saw how to provide the certificate information and how to set its validity in days. Finally, we saw how to read the content of the certificate and how to extract the public key in pem format from it.



Comments and Discussions
Linux Forum