OpenSSL is the toolkit behind most TLS on Linux. Even if Certbot handles your certificates, you’ll eventually need OpenSSL to inspect a certificate, debug a chain, create a CSR for a commercial CA, or convert a PFX file. Here are the commands that matter.

Check your version

openssl version

OpenSSL 3.x is standard on current distributions.

Private keys

# ECDSA P-256 key (modern, small, fast)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out server.key

# RSA 2048/4096 key (maximum compatibility)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out server.key

# Ed25519 key
openssl genpkey -algorithm ED25519 -out ed25519.key

chmod 600 server.key

Inspect a key:

openssl pkey -in server.key -text -noout

Certificate Signing Request (CSR)

Commercial CAs ask for a CSR containing your public key and the domain names:

openssl req -new -key server.key -out server.csr \
  -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com"

Verify what’s in it:

openssl req -in server.csr -noout -text

Browsers use the subjectAltName list, not the CN — make sure every hostname is there.

Self-signed certificate (testing, internal services)

openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
  -keyout selfsigned.key -out selfsigned.crt \
  -subj "/CN=internal.example.lan" \
  -addext "subjectAltName=DNS:internal.example.lan,IP:10.0.0.5"

Browsers will warn because no trusted CA signed it. For internal services, a private CA is cleaner — see self-signed certificates and private CA with step-ca.

Inspect certificates

openssl x509 -in cert.pem -noout -text                    # everything
openssl x509 -in cert.pem -noout -subject -issuer -dates  # the essentials
openssl x509 -in cert.pem -noout -ext subjectAltName      # covered names
openssl x509 -in cert.pem -noout -fingerprint -sha256

Check whether it expires within 30 days (exit code 1 if so — useful in scripts):

openssl x509 -in cert.pem -noout -checkend $((30*24*3600))

Does this key match this certificate?

openssl x509 -in cert.pem -noout -pubkey | openssl sha256
openssl pkey -in server.key -pubout | openssl sha256

Identical hashes = they belong together. A mismatch makes Nginx refuse to start with key values mismatch.

Test a live TLS server

openssl s_client -connect example.com:443 -servername example.com </dev/null

-servername sends SNI — required when one IP hosts several sites. Useful variations:

# Certificate dates and names of the live site
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates

# Show the full chain the server sends
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

# Test a specific TLS version
openssl s_client -connect example.com:443 -tls1_2 </dev/null
openssl s_client -connect example.com:443 -tls1_3 </dev/null

# STARTTLS for mail servers
openssl s_client -connect mail.example.com:587 -starttls smtp

Look for Verify return code: 0 (ok). Code 21 (“unable to verify the first certificate”) usually means the server isn’t sending the intermediate certificate — see SSL certificate chain errors.

Verify a chain locally

openssl verify -CAfile chain.pem cert.pem
openssl verify -untrusted intermediate.pem cert.pem

Convert formats

Format Looks like Used by
PEM Base64 text, -----BEGIN …----- Nginx, Apache, most Linux software
DER Binary Java, some Windows tools
PKCS#12 / PFX Binary bundle of key + cert + chain Windows/IIS, browsers
# PEM → DER
openssl x509 -in cert.pem -outform der -out cert.der

# PFX → PEM (key and certificates)
openssl pkcs12 -in bundle.pfx -nocerts -nodes -out key.pem
openssl pkcs12 -in bundle.pfx -nokeys -out certs.pem

# PEM → PFX (for IIS)
openssl pkcs12 -export -inkey server.key -in cert.pem -certfile chain.pem -out bundle.pfx

OpenSSL 3 may refuse old PFX files using legacy algorithms; add -legacy when reading them.

Random values and hashes

openssl rand -base64 32          # passwords, secrets, API keys
openssl rand -hex 16
openssl dgst -sha256 file.iso     # file hash (same as sha256sum)

Encrypt a file with a password

openssl enc -aes-256-cbc -pbkdf2 -salt -in backup.tar.gz -out backup.tar.gz.enc
openssl enc -d -aes-256-cbc -pbkdf2 -in backup.tar.gz.enc -out backup.tar.gz

For regular use, GPG or age are friendlier and safer defaults — see GPG encryption.

Quick reference

Task Command
New key openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out k.key
CSR openssl req -new -key k.key -out r.csr -subj … -addext subjectAltName=…
Read cert openssl x509 -in c.pem -noout -text
Expiry openssl x509 -in c.pem -noout -dates
Test server openssl s_client -connect host:443 -servername host
Key ↔ cert match compare -pubkey hashes
PFX → PEM openssl pkcs12 -in f.pfx -nodes
Random secret openssl rand -base64 32

For free, automated certificates on your own server, see Let’s Encrypt with Certbot.

  • OpenSSL
  • SSL
  • Security