Certificates2026-04-05

OpenSSL Commands Cheat Sheet: CSR, Certificates, Keys & Debugging

The essential OpenSSL commands for generating CSRs, inspecting certificates, converting formats, testing TLS connections with s_client, and generating keys. Copy-paste ready.

opensslssltlscertificatescsrdevopssysadmin

OpenSSL Commands Cheat Sheet: CSR, Certificates, Keys & Debugging

OpenSSL is the Swiss Army knife of SSL/TLS work. Whether you're generating a CSR, inspecting a certificate's expiry date, converting between PEM and PFX, or debugging a TLS handshake, OpenSSL has a command for it. The challenge is remembering which command does what.

This cheat sheet covers the OpenSSL commands you'll actually use — organized by task, with copy-paste examples and explanations of the important flags.

OpenSSL Essentials

OpenSSL is an open-source cryptographic library and command-line toolkit. It implements TLS/SSL protocols and a wide range of cryptographic operations.

Check your version

openssl version -a

The version matters — some commands and cipher suites differ between OpenSSL 1.x and 3.x. Most modern Linux distributions ship with OpenSSL 3.x. macOS ships with LibreSSL (a compatible fork) but you can install OpenSSL via Homebrew.

Install OpenSSL

Ubuntu/Debian:

sudo apt-get update && sudo apt-get install openssl

RHEL/CentOS/Amazon Linux:

sudo yum install openssl
# or on RHEL 8+
sudo dnf install openssl

macOS (via Homebrew — replaces LibreSSL):

brew install openssl
echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zshrc

Windows: Download a pre-built binary from slproweb.com or use it via WSL, Git Bash, or the openssl command included with Git for Windows.


Certificate Inspection Commands

View a PEM certificate

openssl x509 -in certificate.pem -text -noout

This dumps the full certificate contents: subject, issuer, validity dates, public key, SANs (Subject Alternative Names), key usage, and extensions. The -noout flag suppresses the raw PEM output so you only see the human-readable version.

View just the important fields

# Subject and issuer only
openssl x509 -in certificate.pem -subject -issuer -noout

# Validity dates only
openssl x509 -in certificate.pem -dates -noout

# SHA-256 fingerprint
openssl x509 -in certificate.pem -fingerprint -sha256 -noout

# Subject Alternative Names (SANs)
openssl x509 -in certificate.pem -ext subjectAltName -noout

Check certificate expiry

# Show not-before and not-after dates
openssl x509 -in certificate.pem -dates -noout

# Check how many days until expiry (Linux)
echo "Certificate expires in: $(( ($(date -d "$(openssl x509 -enddate -noout -in certificate.pem | cut -d= -f2)" +%s) - $(date +%s)) / 86400 )) days"

View a DER-encoded certificate

DER is the binary format. Add the -inform DER flag:

openssl x509 -in certificate.der -inform DER -text -noout

View a CSR (Certificate Signing Request)

openssl req -in request.csr -text -noout

This shows the distinguished name, public key, and any SANs or extensions included in the CSR.

View a private key

# RSA key
openssl rsa -in private.key -text -noout

# EC key
openssl ec -in private.key -text -noout

# View key type without knowing it
openssl pkey -in private.key -text -noout

Never share the output of these commands — they contain your private key material.

View a PKCS#12 / PFX file

openssl pkcs12 -in certificate.pfx -info -noout
# You'll be prompted for the PFX password

CSR Generation

A CSR (Certificate Signing Request) is what you submit to a Certificate Authority to get a certificate issued. It contains your public key and identity information.

Generate a new private key and CSR in one command

openssl req -new -newkey rsa:2048 -keyout private.key -out request.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=Acme Corp/CN=example.com"

Flag breakdown:

  • -new — generate a new CSR
  • -newkey rsa:2048 — generate a new 2048-bit RSA key at the same time
  • -keyout private.key — save the private key to this file
  • -out request.csr — save the CSR to this file
  • -subj — provide the subject fields without an interactive prompt

For a 4096-bit key (more secure, but slower TLS handshakes):

openssl req -new -newkey rsa:4096 -keyout private.key -out request.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=Acme Corp/CN=example.com"

Generate a CSR with Subject Alternative Names (SANs)

Modern certificates require SANs for every hostname they should be valid for. Create a config file:

# Create san.cnf
cat > san.cnf << EOF
[req]
default_bits = 2048
prompt = no
distinguished_name = dn
req_extensions = req_ext

[dn]
C = US
ST = California
L = San Francisco
O = Acme Corp
CN = example.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
EOF

# Generate the CSR using the config
openssl req -new -newkey rsa:2048 -keyout private.key -out request.csr -config san.cnf

Generate a CSR from an existing private key

If you already have a private key and just need a new certificate (renewal):

openssl req -new -key existing_private.key -out request.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=Acme Corp/CN=example.com"

Verify a CSR

openssl req -verify -in request.csr -noout
# Should output: verify OK

Certificate Format Conversions

PEM to DER

openssl x509 -in certificate.pem -outform DER -out certificate.der

DER to PEM

openssl x509 -in certificate.der -inform DER -outform PEM -out certificate.pem

PEM to PFX/PKCS#12 (combines cert + key + chain)

openssl pkcs12 -export \
  -in certificate.pem \
  -inkey private.key \
  -certfile chain.pem \
  -out bundle.pfx \
  -name "My Certificate"
# You'll be prompted to set a PFX password

PFX to PEM (extract cert and key)

# Extract certificate
openssl pkcs12 -in bundle.pfx -clcerts -nokeys -out certificate.pem

# Extract private key (will ask for PFX password, then set an output passphrase)
openssl pkcs12 -in bundle.pfx -nocerts -out private.key

# Extract private key without encryption
openssl pkcs12 -in bundle.pfx -nocerts -nodes -out private.key

# Extract the CA chain
openssl pkcs12 -in bundle.pfx -cacerts -nokeys -out chain.pem

CRT + KEY to PFX (combine existing files)

openssl pkcs12 -export -in certificate.crt -inkey private.key -out bundle.pfx

Remove passphrase from a private key

openssl rsa -in encrypted.key -out decrypted.key
# Enter the passphrase when prompted

Testing with openssl s_client

openssl s_client connects to a TLS server and shows you the full handshake — certificates, cipher suites, protocol version. It's the fastest way to debug TLS issues without a browser.

Basic connection

openssl s_client -connect example.com:443

This shows the full certificate chain, cipher suite negotiated, and protocol version. Press Ctrl+C or type quit to exit.

Check the certificate chain

openssl s_client -connect example.com:443 -showcerts

The -showcerts flag dumps every certificate in the chain (leaf + intermediates + root). Without it, you only see the leaf certificate.

Test with SNI (Server Name Indication)

Modern servers host multiple domains on one IP. SNI tells the server which certificate to present:

openssl s_client -connect 1.2.3.4:443 -servername example.com

Always include -servername when the IP hosts multiple domains.

Check certificate expiry via s_client

echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -dates

Test a specific TLS version

# Test TLS 1.2 only
openssl s_client -connect example.com:443 -tls1_2

# Test TLS 1.3 only
openssl s_client -connect example.com:443 -tls1_3

If the connection fails, the server doesn't support that TLS version.

Test with STARTTLS (for SMTP, IMAP, etc.)

# SMTP
openssl s_client -connect mail.example.com:587 -starttls smtp

# IMAP
openssl s_client -connect mail.example.com:143 -starttls imap

Get just the certificate in PEM format

echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -out downloaded_cert.pem

Key Generation and Signing

Generate an RSA private key

# 2048-bit (minimum acceptable for new keys)
openssl genrsa -out private.key 2048

# 4096-bit (higher security, slower)
openssl genrsa -out private.key 4096

# With AES-256 encryption (protects the key with a passphrase)
openssl genrsa -aes256 -out private.key 4096

Generate an EC (Elliptic Curve) private key

EC keys are smaller and faster than RSA at equivalent security levels:

# P-256 (recommended, supported everywhere)
openssl ecparam -name prime256v1 -genkey -noout -out ec_private.key

# P-384 (higher security, US government standard)
openssl ecparam -name secp384r1 -genkey -noout -out ec_private.key

Generate a self-signed certificate

openssl req -x509 -newkey rsa:2048 -keyout private.key -out certificate.pem \
  -days 365 -nodes \
  -subj "/C=US/ST=California/O=Dev/CN=localhost"

The -nodes flag means "no DES" — the private key won't be encrypted with a passphrase. For development use, this is convenient. For production, add encryption.

Self-signed certificate with SANs:

openssl req -x509 -newkey rsa:2048 -keyout private.key -out certificate.pem \
  -days 365 -nodes \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,DNS:*.localhost,IP:127.0.0.1"

Verify a certificate and private key match

The modulus of a certificate and its corresponding private key must be identical:

# Get certificate modulus
openssl x509 -noout -modulus -in certificate.pem | openssl md5

# Get private key modulus
openssl rsa -noout -modulus -in private.key | openssl md5

If both MD5 hashes match, the key and certificate are a pair. If they differ, you have a mismatch.


OpenSSL Quick Reference

Task Command
View certificate openssl x509 -in cert.pem -text -noout
View CSR openssl req -in csr.pem -text -noout
View private key openssl rsa -in key.pem -text -noout
Check expiry dates openssl x509 -in cert.pem -dates -noout
Check SHA-256 fingerprint openssl x509 -in cert.pem -fingerprint -sha256 -noout
Generate RSA key openssl genrsa -out key.pem 2048
Generate key + CSR openssl req -new -newkey rsa:2048 -keyout key.pem -out csr.pem
Self-signed cert openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
PEM → DER openssl x509 -in cert.pem -outform DER -out cert.der
DER → PEM openssl x509 -in cert.der -inform DER -out cert.pem
PEM → PFX openssl pkcs12 -export -in cert.pem -inkey key.pem -out bundle.pfx
PFX → PEM cert openssl pkcs12 -in bundle.pfx -clcerts -nokeys -out cert.pem
PFX → PEM key openssl pkcs12 -in bundle.pfx -nocerts -nodes -out key.pem
Test TLS connection openssl s_client -connect host:443
Check TLS with SNI openssl s_client -connect host:443 -servername domain.com
Verify cert+key match openssl x509 -modulus -in cert.pem | md5sum vs openssl rsa -modulus -in key.pem | md5sum

When a GUI Tool Is Faster

The OpenSSL command line is powerful but verbose. For quick one-off tasks, browser-based tools are often faster — especially when you need to inspect a certificate you received from someone else and don't want to copy it to a file just to run a command:

All of these run entirely in your browser — no data is uploaded to a server.

Common OpenSSL Errors

unable to load Private Key — The key file is encrypted with a passphrase. Use -passin pass:yourpassword or omit -nodes and enter the passphrase interactively.

PEM_read_bio_X509: no start line — The file isn't a valid PEM file, or you're using the wrong -inform. Try adding -inform DER if the file might be binary.

SSL handshake has read 0 bytes — The server is not responding on that port, or it doesn't support TLS (it might expect STARTTLS — use -starttls smtp).

depth=0 ... error 18 at 0 depth lookup: self-signed certificate — Expected for self-signed certs. Add -verify_return_error to make this a hard failure, or use -CAfile to specify the CA for verification.

SSL alert number 40 (handshake failure) — The server rejected the TLS version or cipher suite. Try specifying a different protocol: -tls1_2 or -tls1_3.