OpenSSL is a robust, full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols.
Installation
OpenSSL is pre-installed on most Linux distributions. If missing:
# Debian / Ubuntu
sudo apt install openssl
# RHEL / CentOS / Fedora
sudo dnf install openssl
# Arch Linux
sudo pacman -S opensslCertificate Generation Workflow
1. Generate a Private Key
# Generate a 2048-bit RSA private key
openssl genrsa -out domain.key 2048
# Generate a 4096-bit RSA private key (stronger, slower)
openssl genrsa -out domain.key 4096
# Generate an ECDSA private key (modern, fast, smaller key size)
openssl ecparam -genkey -name prime256v1 -out domain.key2. Generate a Certificate Signing Request (CSR)
Send the CSR to a Certificate Authority (CA) to obtain a signed certificate.
# Interactive (prompts for country, organization, common name, etc.)
openssl req -new -key domain.key -out domain.csr
# Non-interactive (provide subject inline)
openssl req -new -key domain.key -out domain.csr \
-subj "/C=US/ST=California/L=San Francisco/O=MyCompany/CN=example.com"3. Generate a Self-Signed Certificate (For Testing)
Generate the key and a self-signed certificate valid for 365 days in one command.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout domain.key -out domain.crt \
-subj "/CN=example.com"Subject Alternative Names (SAN)
Modern browsers require SAN for multi-domain or wildcard certificates.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout domain.key -out domain.crt \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com,DNS:*.example.com"Viewing and Verifying
# View a certificate's details (issuer, subject, dates, SANs)
openssl x509 -in domain.crt -text -noout
# View a CSR's details
openssl req -in domain.csr -text -noout -verify
# Verify a private key is valid
openssl rsa -in domain.key -check
# Check certificate expiration date only
openssl x509 -in domain.crt -noout -datesVerifying Key / CSR / Certificate Match
Ensure your private key, CSR, and certificate all belong together by comparing modulus hashes. All three must produce the same hash.
openssl x509 -noout -modulus -in domain.crt | openssl md5
openssl rsa -noout -modulus -in domain.key | openssl md5
openssl req -noout -modulus -in domain.csr | openssl md5Format Conversions
# PEM to DER (binary format)
openssl x509 -outform der -in domain.pem -out domain.der
# DER to PEM (text format)
openssl x509 -inform der -in domain.der -out domain.pem
# PEM to PKCS12 (.pfx / .p12) — commonly used by Windows/IIS/Java
openssl pkcs12 -export -out domain.pfx \
-inkey domain.key -in domain.crt -certfile ca-bundle.crt
# PKCS12 to PEM (extract cert and key from .pfx)
openssl pkcs12 -in domain.pfx -out domain.pem -nodesTesting Live Connections
Use OpenSSL to debug HTTPS connections to a remote server.
# Connect to an HTTPS server and view the certificate chain
openssl s_client -connect example.com:443
# Show only the certificate (no handshake details)
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | openssl x509 -text -noout
# Test if a specific TLS version is supported
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
# Check certificate expiration of a remote server
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -datesLet's Encrypt (Certbot)
Certbot automates free certificate issuance from Let's Encrypt.
# Install Certbot
sudo apt install certbot python3-certbot-nginx # For Nginx
sudo apt install certbot python3-certbot-apache # For Apache
# Obtain and auto-configure a certificate for Nginx
sudo certbot --nginx -d example.com -d www.example.com
# Obtain and auto-configure a certificate for Apache
sudo certbot --apache -d example.com -d www.example.com
# Obtain a certificate without modifying web server config (standalone)
sudo certbot certonly --standalone -d example.com
# Renew all certificates (usually set up as a cron job or systemd timer)
sudo certbot renew
# Test renewal without making changes (dry run)
sudo certbot renew --dry-run