Fundamental TLS Certificate Commands You Should Know | by Tate Galbraith | Sep, 2022

Wrapping your head around Public Key Infrastructure (PKI) can be one of the most challenging aspects of software development. Building applications is all fun and games until it comes time to secure their communications. If you create distributed systems that connect to each other on a network, you’re going to run into TLS certificates at some point.

In this article, we’ll face the challenge of managing certificates head on. Learning a few basic commands to generate and inspect certificates makes managing and securing your applications much easier. We’ll explore setting up a private chain of certificates that can be used for testing and examine how each component fits together as a whole.

This is one of the most common tasks in the certificate realm. If you’re building an encrypted network or testing an HTTPS web server, you’ll need to obtain some form of certificate.

The fastest and simplest way to do this is to generate a “self-signed” certificate. This is a standalone certificate that essentially states: “I am the sole authority and I confirm my own identity.”

It should be obvious, but this isn’t actually a secure or trusted certificate. This is because it validates itself. It is “self-signed”. There is no upstream, credible, certificate authority validating it to prove its identity.

If you want to get a valid, trusted certificate you would need to use a free service like Let’s Encrypt or purchase a certificate from a company like DigiCert.

For testing purposes, or internal-only development networks, a self-signed certificate is generally acceptable. Let’s look at how we could generate a self-signed certificate using the openssl utility:

openssl req -new \
-newkey rsa:4096 -nodes \
-x509 \
-days 3650 \
-keyout self_signed.key \
-out self_signed.pem \
-subj '/CN=TestCertificate/C=US/ST=CA/L=SF/O=Test'

Let’s break down what this command is doing at each step starting from the beginning:

  • Create a new certificate request in the PKCS10 format.
  • Generate a new private key for this request 4096 bytes long.
  • Do not encrypt the private key with a password.
  • Output a self-signed certificate (this is the -x509 flag).
  • Make the certificate expire 10 years from now (a longer expiration is normal for offline root CAs).
  • Write the private key to the self_signed.key file.
  • Write the certificate to the self_signed.pem file.
  • Append the specified subject information to the certificate — these are pieces of data like the country, state and organization.

Once we run this command we’ll be left with two important files:

  • The first file ends in .key and is our private key used to form the certificate. This is similar to what you’d use to generate an SSH key pair.
  • The second file ending with .pem is the certificate. Once you have the certificate and the key you can install it into whatever services require encryption.
A self-signed certificate error in Firefox.

Clients that connect to the service will see that it is a self-signed certificate and likely produce some kind of warning. Although this is not a trusted certificate, traffic between the service will technically be encrypted at this point.

Next, let’s look at how we can use our new self-signed certificate to sign other types of certificates.

Now that we have a fancy new self-signed certificate, we could actually use that certificate as a CA and start signing other certificates with it. This creates a chain of trust (albeit a weak one) between certificates and forms the fundamentals of distributed PKI.

Let’s assume you have a new host that you want to issue a certificate for. This host and others within the same domain should all trust one another and have some central reference point. This is the concept of a certificate authority, or CA. We can generate unique certificates for all of our hosts and sign them using a single CA.

In order to sign a host certificate we must first create something called a Certificate Signing Request (CSR). This is a special request created by the host and sent to the CA to be signed and then returned.

Let’s make a new CSR for our TestHost now:

openssl req -new \
-newkey rsa:4096 -nodes \
-keyout host.key \
-out host.csr \
-subj '/CN=TestHost/C=US/ST=CA/L=SF/O=Test'

Again, let’s break this down line-by-line:

  • Create a new certificate request in the PKCS10 format.
  • Generate a new private key for this request 4096 bytes long (again, this key is unencrypted and has no password).
  • Output the private key to the host.key file.
  • Output the CSR to the host.csr file.
  • Append the host subject information.

Once we run this command we’ll have a new CSR file to take with us and sign using our CA. Let’s look at how to do that next.

The final piece of the puzzle is getting our CSR signed. To do this, we’ll take our host.csr file we created earlier and bring it to the CA. This could be on a centralized server, a portal, etc. In this example, it is on the same host where we’ve been testing so we’ll just sign it in place now:

openssl x509 -req \
-in host.csr \
-CA self_signed.pem \
-CAkey self_signed.key \
-CAcreateserial \
-out host.pem \
-days 30 -sha256

Strap in for another line-by-line breakdown of what’s happening:

  • This time we are performing an x509 request, which means we’ll be signing a certificate instead of creating a new request.
  • Provide the host CSR file created earlier as the input.
  • Provide the self-signed CA certificate file.
  • Provide the self-signed CA private key file.
  • Create a serial number file — this will prevent an error from being produced during signing.
  • Output the signed certificate as host.pem
  • The certificate is valid for 30 days and signed using the SHA256 digest.

Once we complete this command we’re left with our final, signed host certificate. We could then use this certificate and any others signed by this CA to build a system of trusted hosts in the domain.

One thing to note here is the shorter expiration for hosts. Most recommendations are around 30 days for host certificates. This forces a renewal every month and ensures that host certs (since hosts are generally more ephemeral) can’t hang around for years at a time.

Since we have a number of certificates floating around in our environment, it is a good idea to learn how to inspect them. Some certificates expire more quickly than others. While an offline root CA might be valid for 10 years, a client certificate could be valid for as short as 24 hours.

Let’s look at how we can use one last openssl command to inspect existing certificates:

openssl x509 -text -noout < cert.pem

This is a simple command that let’s us see quite a bit of information right away. We can immediately learn the following things about a certificate:

  • The issuer
  • The expiration date
  • The subject information
  • Encryption information

There is even more information included in the result, like the encrypted keys and cipher information, but this isn’t usually as helpful when diagnosing problems.

If you’re hunting to determine when a certificate expires or who issued it, this is a wonderful starting point.

Let’s see what our self-signed certificate from the beginning looks like:

Version: 1 (0x0)
Serial Number: 15449774297344832821 (0xd6689fddf532f535)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=TestCertificate, C=US, ST=CA, L=SF, O=Test
Not Before: Sep 21 01:48:35 2022 GMT
Not After : Sep 18 01:48:35 2032 GMT
Subject: CN=TestCertificate, C=US, ST=CA, L=SF, O=Test

Looks pretty good to me. We can quickly tell how long the certificate is valid, where it came from and who it is for.

News Credit

%d bloggers like this: