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.