Skip to main content

How to use OpenSSL and the Internet PKI on Linux systems

A high-level overview of TLS/SSL and the OpenSSL tool, creating private keys and CSRs, and an introduction to the Internet PKI.
How to use OpenSSL and the Internet PKI on Linux systems

Photo by RODNAE Productions from Pexels

This article is part two of three covering encryption concepts and the Internet public key infrastructure (PKI). The first article in this series introduced symmetric and public key (asymmetric) encryption in cryptography. If you're not familiar with the basic concept of public-key encryption, you should read part one before you go ahead with this one.

In this part, I show you the basics of Transport Layer Security and Secure Socket Layer (TLS/SSL), how the Internet PKI works, and OpenSSL, the Swiss Army knife for TLS/SSL tasks. I cover how to use OpenSSL to create key-pairs and to generate a certificate signing request (CSR) to send to your certificate authority (CA) for signing. After that, I discuss some weaknesses of the Internet PKI you should be aware of.

[ You might also enjoy: Security advice for sysadmins: Own IT, Secure IT, Protect IT ]


Assume that you're a sysadmin like me and one of your tasks is to manage a webserver. Because your users care about authenticity, integrity, and privacy, you'd like to secure your web application with some kind of encryption.* You don't know in advance who's using your site, so symmetric encryption is off the table because of its key distribution problem. I use public-key encryption in the following sections instead.


The acronyms for Transport Layer Security and Secure Socket Layer are TLS and SSL. They are used interchangeably most of the time, and that's OK. While the old SSL protocol versions are deprecated, you'll usually find TLSv1.2 and TLSv1.3 on the web these days. TLS is used in HTTPS connections between some clients and some web servers. The following image shows a simple example of an HTTPS handshake.

Handshake with timing data

Full TLS 1.2 Handshake with timing data (Source: Full_TLS_1.2_Handshake.svg)

First, the well-known TCP handshake happens between client and server. Then the client starts the HTTPS handshake by sending the ClientHello. In this step, the client transmits information about the server name it requests and the supported cipher suites. The server responds with the ServerHello, transmits a selected cipher suite, connection parameters, and sends information for calculating a symmetric key for the ongoing connection. Last but not least, it sends its certificate to authenticate itself to the client.

If you would like to get a thorough understanding of TLS and SSL, I recommend the book Bulletproof SSL and TLS by Ivan Ristic.

Focus on the certificate the server has transmitted to the client. It contains the server's public key, which the client uses to encrypt data before sending it to the server. A trusted Certificate Authority (CA) signed the public key in the certificate. Today, every operating system and web browser comes with a store containing the public keys of many different trusted CAs. These public keys are then used to verify the signatures in server certificates like the one discussed here. This way, the client can check the server's authenticity and that it is the correct host the client wants to connect to.

As you can see, public-key encryption is used in this scenario for two tasks:

  1. Verify the authenticity of the server
  2. Use the server's public key to transmit encrypted data to the server

Be aware that public key encryption is used only to establish the HTTPS connections and calculate a symmetric session key used for further communication. That's because symmetric encryption is much faster than asymmetric.


So now the question is, how do you get the key-pair for the webserver? As stated earlier, OpenSSL is the Swiss Army knife for SSL and TLS tasks. Since its documentation has left some room for improvement, I suggest that you read the free book, OpenSSL Cookbook by Ivan Ristic to get all the details. My article focuses on creating a key-pair and a Certificate Signing Request (CSR) for a single domain name and a CSR that includes multiple domain names.

The CSR is needed to send the public key and other information about your domain to a CA for signing. The signed public key you'll get back is your certificate which you will install on your web server along with the corresponding private key.

Creating a private key and a CSR for a single domain

Next, I'll give you an example of creating a private key (RSA 2048 bits) and CSR in one single step. You will enter all information necessary.

$ openssl req -newkey rsa:2048 -keyout -out
Generating a RSA private key
writing new private key to ''
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
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) [AU]:DE
State or Province Name (full name) [Some-State]:EXAMPLE-STATE
Locality Name (eg, city) []:Example City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Ltd
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []
Email Address []

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

You'll find both files in your current working directory. The passphrase you entered during the creation process protects your private key file. If you open them in some kind of text viewer, you'll only recognize that these are a private key and a CSR but won't find further plain text information:

$ cat{key,csr}

Well, that's not very useful for the human mind so in the next section, you'll find the commands to review your private key's parameters and the CSR in a more human-readable form.

Reviewing the private key

Attention: Never share your private key(s) with anyone. They are yours and yours only. Keep them secret, safe, and sound. Follow your organization's policies for handling private keys, CSRs, and certificates. The security of your organization (and your job) may depend on it.

The following example shows you how a private key looks like. In normal operation, there is usually no need to print out a private key like that.

$ openssl pkey -text -noout -in
Enter pass phrase for
RSA Private-Key: (2048 bit, 2 primes)
publicExponent: 65537 (0x10001)

Reviewing the CSR

The following example shows you how to review your CSR before submitting it to a CA for signing.

$ openssl req -text -noout -in
Certificate Request:
        Version: 1 (0x0)
        Subject: C = DE, ST = EXAMPLE-STATE, L = Example City, O = Example Ltd, OU = IT, CN =, emailAddress =
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption

Creating a CSR including multiple domain names

There are situations where your application is reachable under different domain names like:


To create a CSR that contains all three domain names you can use a configuration file. For example, use your favorite text editor to create a file with the following content:

[ req ]
default_bits = 2048
default_keyfile = test_privatekey.pem
distinguished_name = req_distinguished_name
encrypt_key = no
prompt = no
string_mask = nombstr
req_extensions = v3_req

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName =,, DNS:

[ req_distinguished_name ]
countryName = DE
stateOrProvinceName = EXAMPLE-STATE
localityName = Example City
0.organizationName = Example Ltd.
organizationalUnitName = IT
commonName =

The first section [ req ] specifies that a private RSA key with 2048 bits is to be generated and stored as test_privatekey.pem. Also, the section contains information about finding the bits that you entered interactively in the earlier section of this article (in the section [ req_distinguished_name ]. In [ v3_req ], you'll find some constraints on keyUsage but more importantly, for this article, the parameter subjectAltName where the common name and all additional names are specified. Save it as openssl.cnf and run it with the following command to create a private key and CSR:

$ openssl req -batch -new -config openssl.cnf -out
Generating a RSA private key
writing new private key to 'test_privatekey.pem'

$ ls  openssl.cnf  test_privatekey.pem

Be aware in this example, a passphrase does not protect the private key. This comes in handy when you would like a webserver to be able to read it. But keep an eye on it and keep it safe.

The CSR is stored in and you can check the content as before:

$ openssl req -text -noout -in
Certificate Request:
        Version: 1 (0x0)
        Subject: C = DE, ST = EXAMPLE-STATE, L = Example City, O = Example Ltd., OU = IT, CN =
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
        Requested Extensions:
            X509v3 Basic Constraints:
            X509v3 Key Usage:
                Digital Signature, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name:
    Signature Algorithm: sha256WithRSAEncryption

You should recognize the section x509v3 Subject Alternative Name containing all the domain names you need.

Whether you need only one domain name or more in your certificate, you now know how to generate the necessary CSR. For an in-depth understanding, I suggest that you refer to the book I recommended above.

The Internet PKI

Now that you have a CSR ready to get signed by a trusted CA, it's time to examine the Internet PKI. Here's a basic overview. For details, refer to RFC 5280.

In the Internet PKI there are the following roles:

Subscriber - Someone who would like to provide a TLS/SSL secured service. So probably you and me.

Certification Authority (CA) - Verifies the identity of subscribers or their domains and issues certificates that could be installed on web servers. It also provides information about certificates that have been revoked.

Relying Party - This could be a web browser or some other kind of client which tries to validate the certificate sent by your web server. So-called trust anchors are used to verify the certificate. Trust anchors are certificates that are completely trusted and are kept in the browser's trusted CA store.

Usually, the following workflow is completed before a web browser verifies a certificate from your web server.

  1. Generate private key with OpenSSL
  2. Create CSR with OpenSSL
  3. Submit CSR to CA for signing
  4. Receive signed certificate from CA
  5. Install private key and certificate on your web server
  6. Your users/customers can start using your site/app

Remember what you already know about public-key encryption. You could use the private key to sign a message and use the corresponding public key to verify the signature. Something very similar happens when the CA signs your public key and issues your certificate.

The certificate itself is a data structure that includes some information about you or your organization. It contains the domain name, your public key, the name of the CA that issued the certificate, and the CA's signature. To give you an example, I'll show you the certificate that is currently in use on my personal blog and explain the most important sections of it (shortened for a better overview).

$ echo "" |openssl s_client -connect | openssl x509 -text -noout
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN =
verify return:1
        Version: 3 (0x2)
        Serial Number:
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Let's Encrypt, CN = R3
            Not Before: Feb 16 22:34:35 2021 GMT
            Not After : May 17 22:34:35 2021 GMT
        Subject: CN =
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
        X509v3 extensions:

The part after "Certificate:" contains information like the serial number, the signature algorithm used to sign the public key, the name of the issuer, the timeframe in which this cert is valid, the domain name, and the public key. But look at the very first lines as they show the signing path:

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN =
verify return:1

What you see is the chain of trust. You could see that this certificate (the public key associated with the FQDN was signed by Let's Encrypt R3 (R3 is the name of the certificate) which in turn was signed by Digital Signature Trust Co. DST Root CA X3 (here DST Root CA X3 is the name of the certificate).

But how does your browser know whether to trust one of these certificates? The DST Root CA X3 certificate is stored in your browser's trust anchor. See the following image, which shows my browser's trust anchor:

Author's browser's trust anchor

This entry tells your browser to trust all certificates that were signed by DST Root CA X3. A chain of trust is built up to my leaf certificate for The following figure illustrates how the chain of trust works.

The chain of trust

Image Source: Yuhkih, CC BY-SA 4.0.

Notice that between your end-entity certificate and a trust anchor in your browser's store there may be more than one intermediate certificate. It's important that your browser can verify each certificate along the chain to verify your leaf certificate. That's important to notice because if your browser misses one of the intermediate certificates, your certificate's verification will fail.

Usually, you'll get a full chain certificate from your CA, including your certificate and all intermediates involved, down to some root cert residing in your browser trust anchor. It's considered a best practice to configure your webserver to deliver the full chain to make sure your users have a nice experience visiting your site.

[ Thinking about security? Check out this free guide to boosting hybrid cloud security and protecting your business. ] 

Wrap up

In the first article of this series, you learned the basics of encryption concepts. In this article, you received a high-level overview about TLS/SSL and the OpenSSL tool, learning how to create private keys and CSRs, which you could send to a CA for signing. Also, the Internet PKI was introduced with the chain of trust, showing how the verification process works.

In the next article of this series, I'll look at some Internet PKI issues and what you can do about them.

*Of course, there is another reason: Your website will receive a lower ranking in search results if not using TLS/SSL encryption.

Topics:   Linux   Linux administration   Security  
Author’s photo

Jörg Kastning

Jörg has been a Sysadmin for over ten years now. His fields of operation include Virtualization (VMware), Linux System Administration and Automation (RHEL), Firewalling (Forcepoint), and Loadbalancing (F5). More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.