Transport Layer Security (TLS) is the foundation of secure communication on the internet. Certificates, private keys, and certificate chains ensure data confidentiality and authenticity. While most certificates come from trusted Certificate Authorities (CAs), there are many cases where you need to create and validate certificates yourself, especially in development, testing, or internal corporate environments. This guide walks you through common OpenSSL operations with examples.

This post uses .crt extension for files in PEM format that represents a certificate. The same files are commonly used with .pem extension, which is totally fine. PEM is a format, not a file type, meaning files can have extensions like .pem, .crt, .cer, or .key but still contain data in the PEM format.


1. Creating a Self-Signed Certificate Using OpenSSL (Elliptic Curve)

Self-signed certificates are useful for internal testing or non-production environments. With OpenSSL you can generate elliptic curve (EC) keys and a self-signed certificate:

# Generate an EC private key using the prime256v1 curve
openssl ecparam -name prime256v1 -genkey -noout -out ec_private.key

# Create a Certificate Signing Request (CSR)
openssl req -new -key ec_private.key -out ec_request.csr -subj "/C=NL/ST=South Holland/L=Rotterdam/O=MyOrg/OU=IT/CN=example.local"

# Create a self-signed certificate valid for 365 days
openssl x509 -req -in ec_request.csr -signkey ec_private.key   -out ec_certificate.crt -days 365

2. Checking If CSR, Private Key, and Certificate Match

To ensure the private key, CSR, and certificate belong to the same cryptographic identity, compare their public key hashes:

# Extract the public key from the private key
openssl ec -in ec_private.key -pubout -out ec_public.key

# Check modulus or public key fingerprints
openssl pkey -in ec_private.key -pubout -outform pem | sha256sum
openssl req -in ec_request.csr -pubkey -noout -outform pem | sha256sum
openssl x509 -in ec_certificate.crt -pubkey -noout -outform pem | sha256sum

All three hashes must match. This confirms the CSR, private key, and certificate correspond to the same key pair.


3. Extracting Information About a Certificate

OpenSSL can display the details of a certificate:

# Human-readable output
openssl x509 -in ec_certificate.crt -text -noout

# Only the subject and issuer
openssl x509 -in ec_certificate.crt -noout -subject -issuer

This is helpful for auditing or validating certificate attributes such as Subject Alternative Names (SANs), signature algorithm, and validity period.


4. Building a Certificate Chain (Leaf, Intermediate, Root)

In a production-like setup, you’ll often deal with certificate chains. A chain consists of:

  • Leaf (end-entity) certificate: Identifies the service.
  • Intermediate CA certificate: Issued by a root CA.
  • Root CA certificate: Trusted by clients.

To create a chain file:

# Concatenate in order: Leaf + Intermediate(s) + Root
cat certificate.crt intermediate.crt rootCA.crt > full_chain.crt

Servers typically serve the full chain to clients so browsers or API clients can validate the entire trust path.


5. Checking for the Expiration Date of a Certificate

Knowing when a certificate expires is critical for avoiding outages:

# Local certificate file
openssl x509 -in ec_certificate.crt -noout -enddate

# Remote server certificate
echo | openssl s_client -connect example.local:443 -showcerts | openssl ctrl2pkcs -nocrl | openssl pkcs7 -noout -print_certs

This outputs the “notBefore” and “notAfter” fields, showing validity intervals.


6. Calling an API Using a Client Certificate

Some APIs require mutual TLS (mTLS). With curl you can run a test to check if you have the correct certificates.

curl --cert ec_certificate.crt \
     --key ec_private.key \
     --cacert rootCA.crt \
     https://api.example.local/secure-endpoint
  • --cert is your client certificate.
  • --key is the matching private key.
  • --cacert is the certificate chain used to verify the server certificate.

The file passed to –cacert parameter can contain a full chain (leaf + intermediare + root CA), or just a partial chain (intermediare + root CA). The first option is more secure, since it matches the leaf certificate as well. The seconde option is more flexible and allow you to still do successful calls to the api, even if the server rotates the certificate, given that they still sign with the same intermediare and root CAs.


Real-World Applications

  1. Internal Development and Testing: Quickly create and manage self-signed certificates to simulate production-grade TLS for local or test environments.
  2. Enterprise Infrastructure Security: Use OpenSSL to verify third-party certificates, inspect certificate chains, or troubleshoot mutual TLS issues in microservice architectures.

By mastering these OpenSSL commands, you can confidently create, inspect, and troubleshoot certificates — a crucial skill for software engineers, cloud engineers, and solution architects.