OpenSSL Guide
Overview
OpenSSL is a powerful, open-source cryptographic toolkit that implements the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols, providing a robust foundation for secure communications. This comprehensive guide covers both fundamental concepts and practical applications of OpenSSL for certificate management, encryption, and cryptographic operations.
With its versatile capabilities, OpenSSL enables security professionals, system administrators, and developers to:
- Create and manage digital certificates and certificate authorities (CAs)
- Configure secure server communications with strong encryption
- Generate and manage cryptographic keys of various types and strengths
- Test and validate SSL/TLS implementations for security vulnerabilities
- Convert certificates between different formats and standards
- Implement secure authentication mechanisms
- Encrypt sensitive data using industry-standard algorithms
- Develop security-focused applications with cryptographic functionality
As one of the most widely deployed security toolkits in the world, OpenSSL secures approximately 70% of web servers globally and forms a critical component in countless security-critical applications and infrastructure.
Note
This guide is designed to be practical and hands-on, with ready-to-use command examples and real-world scenarios. Commands are tested with OpenSSL 3.x, with notes for version-specific differences where relevant.
OpenSSL Versions
OpenSSL has evolved significantly over time with critical security improvements in each major release. Understanding version differences is essential when working across different environments, particularly for security-critical applications.
Version History
Version | Release Date | Support Status | Key Features & Security Notes |
---|---|---|---|
3.2.x | 2023-Present | Active Development | Expanded QUIC API, optimized memory usage, improved TLS implementation, enhanced FIPS provider |
3.1.x | 2023-Present | Active Development | Enhanced FIPS compliance, certificate policy improvements, memory leak fixes, expanded provider architecture |
3.0.x | 2021-Present | Active Development | Modern provider architecture, enhanced FIPS support, improved command structure, security hardening, memory leak fixes |
1.1.1 | 2018-2023 | Extended Support | TLS 1.3 support, significant security improvements, CHACHA20 and POLY1305 support, enhanced protocol hardening |
1.0.2 | 2014-2019 | End of Life | TLS 1.2, Suite B, post-Heartbleed security improvements |
1.0.1 | 2012-2017 | End of Life | ECDHE, TLS 1.1/1.2, affected by Heartbleed vulnerability (CVE-2014-0160) |
0.9.8 | 2005-2015 | Obsolete | Historic version, lacks modern security features, contains numerous vulnerabilities |
Critical Security Vulnerabilities by Version
Version | Notable Vulnerabilities | Impact |
---|---|---|
3.0.0-3.0.7 | CVE-2022-3786, CVE-2022-3602 (X.509 Email Address Buffer Overflows) | Remote code execution possible |
3.0.0-3.0.6 | CVE-2022-2274 (AES OCB mode) | Remote code execution via cryptographic operations |
1.0.1-1.0.1f | CVE-2014-0160 (Heartbleed) | Memory exposure including private keys |
All versions before 1.1.1 | Various TLS downgrade attacks | Protocol version and cipher downgrades |
1.0.2-1.0.2a | CVE-2015-0291 | Denial of service via client certificate verification |
Version Verification
Always verify the OpenSSL version in your environment before executing commands, as syntax and capabilities may vary between versions:
# Display full version information
openssl version -a
# Check if your version supports a specific feature (e.g., TLS 1.3)
openssl ciphers -v | grep TLSv1.3
# List supported cipher suites
openssl ciphers -v 'ALL'
# Check supported elliptic curves
openssl ecparam -list_curves
Important
Security Alert: Using outdated OpenSSL versions poses significant security risks. Known vulnerabilities in older versions (like Heartbleed in 1.0.1) can be exploited to compromise cryptographic operations, leak sensitive data, or bypass security controls entirely. Always use OpenSSL 1.1.1 or later (preferably 3.x) in any production environment. If you're running a version older than 1.1.1, update immediately as a security priority.
Table of Contents
- Installation
- Basic Concepts
- Certificate Operations
- Certificate Validation and Troubleshooting
- Private Key Management
- CSR Creation and Management
- Certificate Conversions
- SSL/TLS Testing
- Advanced Operations
- Troubleshooting
- Security Considerations
- Best Practices
- References
Installation
OpenSSL is included in most Linux distributions and macOS by default, but it's essential to ensure you're using a current version with all security patches applied. This section covers installation and verification across major platforms.
Linux
Most Linux distributions include OpenSSL packages in their standard repositories, but these may not always be the latest version:
# Debian/Ubuntu
sudo apt update
sudo apt install openssl libssl-dev
# Red Hat/CentOS/Fedora
sudo dnf install openssl openssl-devel
# Arch Linux
sudo pacman -S openssl
# Alpine Linux
apk add openssl
# Verify installation
openssl version -a
For the latest version (especially on older distributions), consider building from source:
# Install build dependencies
sudo apt install build-essential checkinstall zlib1g-dev
# Download source (always check for the latest version)
wget https://www.openssl.org/source/openssl-3.1.3.tar.gz
tar -zxf openssl-3.1.3.tar.gz
cd openssl-3.1.3
# Configure, build, and install
./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared
make
make test
sudo make install
# Update system links and configuration
sudo ln -sf /usr/local/ssl/bin/openssl /usr/bin/openssl
sudo ldconfig
Windows
Windows does not include OpenSSL by default. Several installation options are available:
# Using Chocolatey (recommended method)
choco install openssl
# Using Scoop
scoop install openssl
# Using winget
winget install ShiningLight.OpenSSL
You can also download pre-compiled binaries from:
Tip
For Windows installations:
- Ensure OpenSSL is added to your PATH environment variable
- Verify with
where openssl
in Command Prompt orGet-Command openssl
in PowerShell - If you need to run multiple versions, use full paths to the specific executables
macOS
macOS includes OpenSSL by default, but Apple has deprecated it in favor of LibreSSL. For the most current OpenSSL version, use Homebrew:
# Install using Homebrew
brew install openssl@3
# For OpenSSL 3.x, the installation path is typically:
# /usr/local/opt/openssl@3/ or /opt/homebrew/opt/openssl@3/
# Add to your PATH (add to your .bash_profile, .zshrc, etc.)
echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Verify installation and path
which openssl
openssl version -a
Docker Containers
For isolated testing or deployment, consider using Docker:
# Pull official OpenSSL container
docker pull alpine/openssl
# Run OpenSSL commands in container
docker run -it --rm alpine/openssl version -a
# Use volumes to access local files
docker run -it --rm -v $(pwd):/work -w /work alpine/openssl req -new -x509 -nodes -out cert.pem -keyout key.pem
Environment Variables
Configure these environment variables for easier OpenSSL usage:
# For Linux/macOS (add to shell profile)
export OPENSSL_CONF=/path/to/openssl.cnf
export SSL_CERT_DIR=/path/to/certs
export SSL_CERT_FILE=/path/to/cert.pem
# For Windows (PowerShell)
$env:OPENSSL_CONF = "C:\path\to\openssl.cnf"
$env:SSL_CERT_DIR = "C:\path\to\certs"
$env:SSL_CERT_FILE = "C:\path\to\cert.pem"
Verifying a Proper Installation
Ensure your installation is working correctly with this comprehensive test:
# 1. Check version and compilation details
openssl version -a
# 2. View available commands
openssl help
# 3. List supported ciphers
openssl ciphers -v | head -10
# 4. Test key generation
openssl genrsa -out test.key 2048
# 5. Generate a self-signed certificate
openssl req -new -key test.key -x509 -days 1 -out test.crt -subj "/CN=test"
# 6. Verify the certificate
openssl x509 -in test.crt -text -noout
# 7. Test encryption/decryption
echo "Test data" > testfile.txt
openssl enc -aes-256-cbc -salt -in testfile.txt -out testfile.enc -k testpassword
openssl enc -d -aes-256-cbc -in testfile.enc -out testfile.dec -k testpassword
diff testfile.txt testfile.dec
# 8. Clean up test files
rm test.key test.crt testfile.txt testfile.enc testfile.dec
# If all commands complete without errors, your installation is working properly
Note
If you encounter any issues during verification, ensure your path is correctly set and that any required libraries are installed. For OpenSSL errors, include the -d
flag (e.g., openssl req -d ...
) to enable debug output.
Basic Concepts
Key Concepts in Public Key Infrastructure (PKI)
Public Key Cryptography: Asymmetric encryption using key pairs where data encrypted with a public key can only be decrypted with the corresponding private key. This forms the foundation of secure communications on the internet.
X.509 Certificates: Standardized digital document format that binds a public key to an identity. Contains information about the key, the identity of its owner (called the subject), the digital signature of the entity that verified the certificate's contents (the issuer), and a validity period.
Certificate Authorities (CAs): Trusted entities that issue and sign certificates after verifying the identity of the certificate applicant. Examples include commercial CAs like DigiCert, Let's Encrypt, and Sectigo, as well as private CAs established within organizations.
Certificate Chains: A hierarchical trust structure consisting of a root CA certificate, zero or more intermediate CA certificates, and end-entity certificates. This chain establishes a path of trust from end-entity certificates to trusted root CAs.
Root Certificates: Self-signed certificates at the top of trust chains, representing the ultimate trust anchor in PKI. Operating systems and browsers come pre-installed with a set of trusted root certificates.
Certificate Revocation: The process of invalidating certificates before their expiration date using Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP).
Cryptographic Concepts
Symmetric Encryption: Uses the same key for both encryption and decryption (e.g., AES, 3DES).
Asymmetric Encryption: Uses key pairs - a public key for encryption and a private key for decryption (e.g., RSA, ECC).
Hash Functions: One-way functions that convert data of any size to a fixed-size output (e.g., SHA-256, SHA-3).
Digital Signatures: Created by encrypting a hash of the message with the sender's private key, providing authentication, non-repudiation, and integrity.
OpenSSL Architecture
OpenSSL consists of three main components:
- SSL/TLS Library: Implements the SSL and TLS protocols for secure communications
- Cryptographic Library: Provides general-purpose cryptographic functions
- Command-Line Interface (CLI): Offers tools for various cryptographic operations
OpenSSL Configuration File
The OpenSSL configuration file (openssl.cnf
) defines default settings used by OpenSSL commands. Its location varies by system:
- Linux:
/etc/ssl/openssl.cnf
or/usr/lib/ssl/openssl.cnf
- macOS:
/usr/local/etc/openssl/openssl.cnf
or/opt/homebrew/etc/openssl@3/openssl.cnf
- Windows:
C:\Program Files\OpenSSL-Win64\bin\openssl.cfg
You can specify a different configuration file using the -config
flag or by setting the OPENSSL_CONF
environment variable.
Common OpenSSL Commands
OpenSSL provides a rich set of commands for different cryptographic operations:
# Display OpenSSL version
openssl version -a
# Display all available commands
openssl help
# Display help for a specific command
openssl x509 -help
# List available ciphers
openssl ciphers -v
# List available elliptic curves
openssl ecparam -list_curves
# Generate a random sequence of bytes
openssl rand -base64 32
# Encrypt a file with AES-256
openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.bin
# Decrypt an encrypted file
openssl enc -aes-256-cbc -d -in encrypted.bin -out decrypted.txt
Command Structure
Most OpenSSL commands follow this general structure:
openssl command [command_options] [command_arguments]
Where:
command
: The primary operation (e.g.,x509
,req
,genrsa
)command_options
: Flags that modify the command's behaviorcommand_arguments
: Input/output files and other parameters
Certificate Operations
OpenSSL provides a robust set of tools for creating, inspecting, and managing X.509 certificates. This section covers the most common certificate operations and recommended practices.
Creating Self-Signed Certificates
Self-signed certificates are useful for development environments, internal services, and testing. They are not suitable for production public-facing services as they generate browser warnings.
# Generate a self-signed certificate valid for 365 days
openssl req -x509 -newkey rsa:4096 -keyout private.key -out certificate.crt -days 365 -nodes
# Generate a self-signed certificate with subject information
openssl req -x509 -newkey rsa:4096 -keyout private.key -out certificate.crt -days 365 -nodes \
-subj "/C=US/ST=State/L=City/O=Organization/OU=Department/CN=example.com"
# Generate a self-signed certificate with modern extensions and SHA-256
openssl req -x509 -newkey rsa:4096 -keyout private.key -out certificate.crt -days 365 -nodes \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com" \
-addext "extendedKeyUsage=serverAuth" \
-sha256
Note
Modern browsers require Subject Alternative Names (SANs) for proper certificate validation. The -addext
option is available in OpenSSL 1.1.1 and later.
Best practices for self-signed certificates:
- Use RSA 2048 bits or higher (4096 recommended) or ECC (Elliptic Curve) keys
- Always include Subject Alternative Names (SANs)
- Limit validity period (1 year maximum for development)
- Store private keys securely with appropriate permissions
For a comprehensive guide on self-signed certificates, see the Self-Signed Certificates page.
Viewing Certificate Information
Inspect certificate details to verify content and configuration:
# View complete certificate information in text format
openssl x509 -in certificate.crt -text -noout
# View certificate issuer
openssl x509 -in certificate.crt -issuer -noout
# View certificate subject
openssl x509 -in certificate.crt -subject -noout
# View certificate validity dates
openssl x509 -in certificate.crt -dates -noout
# View certificate validity dates in human-readable format
openssl x509 -in certificate.crt -noout -enddate | sed 's/notAfter=/Expires: /'
openssl x509 -in certificate.crt -noout -startdate | sed 's/notBefore=/Valid from: /'
# Calculate days until certificate expiration
openssl x509 -in certificate.crt -noout -enddate | cut -d= -f2 | xargs -I{} bash -c 'echo $(( ($(date -d "{}" +%s) - $(date +%s)) / 86400 )) days until expiration'
# View certificate fingerprint (SHA-256)
openssl x509 -in certificate.crt -fingerprint -sha256 -noout
# Check the certificate's purpose
openssl x509 -in certificate.crt -purpose -noout
# Extract the public key from a certificate
openssl x509 -in certificate.crt -pubkey -noout > pubkey.pem
# Check extensions (including SANs)
openssl x509 -in certificate.crt -text -noout | grep -A 10 "X509v3 Subject Alternative Name"
# Show the serial number (useful for certificate revocation)
openssl x509 -in certificate.crt -noout -serial
# Display the certificate in a human-readable format without header/footer
openssl x509 -in certificate.crt -noout -text -nameopt oneline,utf8,-esc_msb
# Check certificate chain
openssl verify -CAfile ca-chain.pem certificate.crt
# Checking certificate expiration date in human-readable format
openssl x509 -enddate -noout -in certificate.crt | sed 's/notAfter=/Expires: /'
Tip
For routine certificate monitoring, create a simple shell script that checks expiration dates and alerts when certificates are nearing expiration (e.g., 30 days before).
Certificate Chain Verification
Validating certificate chains is crucial for ensuring trust in the PKI infrastructure. A proper certificate chain connects an end-entity certificate to a trusted root CA through zero or more intermediate certificates.
# Verify a certificate against a trusted CA certificate
openssl verify -CAfile rootca.crt certificate.crt
# Verify a certificate with intermediate certificates
openssl verify -CAfile rootca.crt -untrusted intermediate.crt certificate.crt
# Alternative approach using a certificate bundle
cat intermediate.crt rootca.crt > ca-bundle.crt
openssl verify -CAfile ca-bundle.crt certificate.crt
# Verify a certificate with a complete chain (for web servers)
cat certificate.crt intermediate.crt rootca.crt > fullchain.pem
openssl verify -CAfile rootca.crt -untrusted intermediate.crt certificate.crt
# Display the full certificate chain from a remote server
openssl s_client -connect example.com:443 -showcerts
# Extract and verify individual certificates from a chain
openssl s_client -connect example.com:443 -showcerts </dev/null | \
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
Common certificate chain issues include:
- Missing Intermediate Certificates: The chain is incomplete, causing trust failures
- Incorrect Chain Order: Certificates not in proper sequence from end-entity to root
- Expired Certificates in Chain: Any certificate in the chain has expired
- Cross-Signed Certificates: Complex chains with cross-signed intermediate certificates
Important
Always include the complete certificate chain in server configurations. Missing intermediate certificates are one of the most common causes of certificate validation failures in client applications.
Certificate Formats and Conversions
X.509 certificates can be stored in different formats depending on the application requirements:
# Convert PEM to DER format
openssl x509 -in certificate.pem -outform der -out certificate.der
# Convert DER to PEM format
openssl x509 -inform der -in certificate.der -out certificate.pem
# Convert PEM certificate to PKCS#12 (PFX) format including private key
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile ca-chain.pem
# Extract certificate and key from PKCS#12 (PFX) file
openssl pkcs12 -in certificate.pfx -nocerts -out private.key -nodes
openssl pkcs12 -in certificate.pfx -nokeys -out certificate.crt
# Create a full chain certificate by concatenating certificates
cat certificate.crt intermediate.crt rootca.crt > fullchain.pem
Common certificate formats:
Format | Description | Common Usage |
---|---|---|
PEM (.pem, .crt, .cer) | Base64 encoded with header/footer | Most web servers, OpenSSL |
DER (.der, .cer) | Binary format | Java applications, Windows |
PKCS#7 (.p7b, .p7c) | Certificate containers, no private key | Windows, Java Keystores |
PKCS#12 (.pfx, .p12) | Contains certificates and private keys | Windows, macOS, mobile devices |
Creating a Certificate Authority (CA)
Setting up your own CA is useful for managing certificates within an organization or for development environments. This example creates a complete CA structure:
# 1. Create a directory structure for your CA
mkdir -p ca/{certs,crl,newcerts,private}
touch ca/index.txt
echo 1000 > ca/serial
# 2. Create a CA configuration file
cat > ca.conf << EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./ca
certs = \$dir/certs
crl_dir = \$dir/crl
new_certs_dir = \$dir/newcerts
database = \$dir/index.txt
serial = \$dir/serial
RANDFILE = \$dir/private/.rand
private_key = \$dir/private/ca.key
certificate = \$dir/certs/ca.crt
crl = \$dir/crl/ca.crl
crlnumber = \$dir/crlnumber
crl_extensions = crl_ext
default_crl_days = 30
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 365
preserve = no
policy = policy_strict
[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
x509_extensions = v3_ca
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ server_cert ]
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF
# 3. Create a private key for the CA
openssl genrsa -aes256 -out ca/private/ca.key 4096
chmod 400 ca/private/ca.key
# 4. Create a self-signed CA certificate
openssl req -config ca.conf -key ca/private/ca.key -new -x509 -days 3650 -sha256 \
-extensions v3_ca -out ca/certs/ca.crt
# 5. Verify the CA certificate
openssl x509 -noout -text -in ca/certs/ca.crt
Important
Best practices for managing a Certificate Authority:
- Keep the CA private key extremely secure, preferably offline
- Use strong passphrases for CA keys
- Set appropriate validity periods (root CAs can be valid for 10+ years)
- Implement strict issuance policies
- Maintain proper revocation mechanisms (CRLs and/or OCSP)
- Consider a two-tier CA hierarchy with root and intermediate CAs for added security
Signing Certificates with Your CA
Once your CA is set up, you can sign certificate requests. This is the typical workflow for issuing certificates from your CA:
# 1. Create a server key and CSR
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
# 2. Create a configuration file for the server certificate
cat > server.conf << EOF
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF
# 3. Sign the CSR with the CA
openssl ca -config ca.conf -extensions server_cert -days 365 -notext \
-md sha256 -in server.csr -out server.crt -extfile server.conf
# 4. Verify the signed certificate
openssl verify -CAfile ca/certs/ca.crt server.crt
# 5. Create a certificate chain file (if needed)
cat server.crt ca/certs/ca.crt > server-chain.crt
Certificate validity periods should follow industry best practices:
Certificate Type | Recommended Validity | Notes |
---|---|---|
Root CA | 10-20 years | Keep offline, used only to sign intermediates |
Intermediate CA | 5-10 years | Used for routine certificate signing |
Server/Client | 1 year or less | Public CAs now limit to 398 days |
Code Signing | 1-3 years | Often requires hardware security |
Email (S/MIME) | 1-3 years | Tied to individual identity |
Note
Starting September 2020, major browsers limit the maximum validity period of publicly trusted TLS certificates to 398 days.
Creating Certificates with Subject Alternative Names (SANs)
Modern browsers require Subject Alternative Names (SANs) for proper certificate validation. Here's a comprehensive approach:
# 1. Create a configuration file for SANs
cat > san.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = example.com
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
DNS.4 = admin.example.com
IP.1 = 192.168.1.1
EOF
# 2. Generate key and CSR with SANs
openssl req -new -nodes -newkey rsa:2048 -keyout server_san.key \
-out server_san.csr -config san.conf
# 3. Verify the SANs in the CSR
openssl req -in server_san.csr -noout -text | grep -A 1 "Subject Alternative Name"
# 4. Sign the CSR with your CA (if you have one)
# openssl ca -config ca.conf -extensions v3_req -days 365 -notext \
# -md sha256 -in server_san.csr -out server_san.crt -extfile san.conf
# For self-signed certificate with SANs:
openssl x509 -req -in server_san.csr -signkey server_san.key \
-out server_san.crt -days 365 -sha256 -extfile san.conf -extensions v3_req
# 5. Verify SANs in the final certificate
openssl x509 -in server_san.crt -text -noout | grep -A 1 "Subject Alternative Name"
Warning
If SANs are not included in a certificate, modern browsers will show security warnings regardless of whether the Common Name (CN) matches the domain. Always include all domain names that will be used with the certificate.
SANs can include:
- Multiple domain names (DNS.x entries)
- IP addresses (IP.x entries)
- Email addresses (email.x entries)
- URI entries (URI.x entries)
Wildcard Certificates
Wildcard certificates secure a domain and all its first-level subdomains. They provide flexibility but have security tradeoffs:
# Create a wildcard certificate configuration
cat > wildcard.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = *.example.com
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.example.com
DNS.2 = example.com
EOF
# Generate a wildcard certificate (self-signed for testing)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout wildcard.key -out wildcard.crt -config wildcard.conf
# Verify the wildcard certificate
openssl x509 -in wildcard.crt -text -noout | grep -A 1 "Subject Alternative Name"
Note
Wildcard certificates have important limitations:
- They only cover one level of subdomains (*.example.com covers test.example.com but not sub.test.example.com)
- Compromise of a wildcard certificate affects all subdomains
- Some security standards (like PCI DSS) restrict wildcard certificate usage
- They expose a larger attack surface if the private key is compromised
Consider using multi-domain certificates with explicit SANs as a more secure alternative to wildcards in high-security environments.
Managing Certificate Revocation Lists (CRLs)
When certificates need to be invalidated before expiry, CRLs provide a way to notify clients:
# 1. Ensure CRL number file exists
echo 01 > ca/crlnumber
# 2. Create a CRL configuration file
cat > crl.conf << EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./ca
database = \$dir/index.txt
crlnumber = \$dir/crlnumber
default_days = 30
default_crl_days = 30
default_md = sha256
[ crl_ext ]
authorityKeyIdentifier=keyid:always
EOF
# 3. Generate an initial CRL
openssl ca -config crl.conf -gencrl -out ca/crl/ca.crl
# 4. View CRL information
openssl crl -in ca/crl/ca.crl -text -noout
# 5. Revoke a certificate (specify a reason)
openssl ca -config ca.conf -revoke server.crt -crl_reason keyCompromise
# Valid reasons: unspecified, keyCompromise, CACompromise, affiliationChanged,
# superseded, cessationOfOperation, certificateHold, removeFromCRL
# 6. Generate updated CRL after revocation
openssl ca -config crl.conf -gencrl -out ca/crl/ca.crl
# 7. Configure web server to serve the CRL at a well-known URL
# Example for nginx:
# location /crl/ {
# types { } default_type "application/pkix-crl";
# alias /path/to/ca/crl/;
# }
# 8. Update certificates to include CRL distribution point
# Add to the [v3_req] section in your certificate config:
# crlDistributionPoints = URI:http://example.com/crl/ca.crl
CRL vs. OCSP
Certificate revocation status can be checked through two main methods:
Method | Advantages | Disadvantages |
---|---|---|
CRL | Simple implementation | Can grow large over time |
Works offline once downloaded | Potentially stale data | |
Single file for many certificates | Full list must be downloaded | |
OCSP | Real-time status | Requires online verification |
Smaller network footprint | Privacy concerns | |
More current information | Single point of failure | |
Only queries needed certificates | More complex to implement |
For high-security environments, consider implementing both CRL and OCSP for redundancy.
Certificate Validation and Troubleshooting
Verifying certificates and diagnosing issues is a critical part of certificate management:
# Verify a certificate against a CA certificate
openssl verify -CAfile ca.crt certificate.crt
# Verify a certificate chain
openssl verify -CAfile ca-chain.pem certificate.crt
# Check if a private key matches a certificate
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
# If the outputs match, the key corresponds to the certificate
# Check the hostname against the certificate (OpenSSL 1.1.1+)
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -checkhost example.com
# Test an HTTPS connection and view the certificate
openssl s_client -connect example.com:443 -servername example.com
# Test an HTTPS connection with full certificate chain verification
openssl s_client -connect example.com:443 -servername example.com -CAfile ca-chain.pem -verify_return_error
# Check certificate expiration date
openssl x509 -enddate -noout -in certificate.crt
# List all common SSL/TLS problems for a website
openssl s_client -connect example.com:443 -servername example.com -showcerts -tlsextdebug -status
Certificate Revocation Status Checking
Certificate revocation is crucial for maintaining PKI security. OpenSSL provides ways to check if certificates have been revoked through CRLs and OCSP:
# Download a CRL from a distribution point
curl -s http://crl.example.com/ca.crl > ca.crl
# Convert a CRL from DER to PEM format if needed
openssl crl -inform DER -in ca.crl -outform PEM -out ca.crl.pem
# View CRL information
openssl crl -in ca.crl.pem -text -noout
# Verify a certificate against a CRL
openssl verify -crl_check -CAfile ca.crt -CRLfile ca.crl.pem certificate.crt
# Check OCSP status of a certificate
openssl ocsp -issuer issuer.crt -cert certificate.crt -url http://ocsp.example.com -text
# Check OCSP stapling during TLS connection
openssl s_client -connect example.com:443 -status -servername example.com
# Extract CRL distribution points from a certificate
openssl x509 -in certificate.crt -text -noout | grep -A 3 "CRL Distribution"
# Extract OCSP responder URL from a certificate
openssl x509 -in certificate.crt -text -noout | grep -A 3 "Authority Information Access"
Important
Revocation checking is often overlooked but is essential for complete certificate validation. Both CRL and OCSP have advantages:
- CRLs: Work offline once downloaded, but can grow large and become stale
- OCSP: Provides real-time status, more efficient, but requires continuous online access
Common Certificate Problems and Solutions
Problem | Possible Causes | Solutions |
---|---|---|
Certificate not trusted | Missing CA in trust store | Add CA certificate to system trust store |
Incomplete certificate chain | Include intermediate certificates | |
Certificate expired | Not renewed in time | Generate and install new certificate |
Name mismatch | Wrong hostname in certificate | Use correct hostname or add to SAN |
Accessing by IP, not hostname | Use proper DNS name matching certificate | |
Self-signed warning | Certificate not signed by trusted CA | Install certificate from trusted CA |
Revoked certificate | Certificate compromised | Generate new key pair and certificate |
Weak signature algorithm | Old certificate using SHA-1 | Generate new certificate using SHA-256 |
Automated Certificate Monitoring
Regular certificate monitoring helps prevent unexpected expirations:
# Sample shell script to check certificate expiry
#!/bin/bash
CERT_FILE="certificate.crt"
DAYS_WARNING=30
# Get expiration date in seconds since epoch
EXPIRY=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
echo "WARNING: Certificate $CERT_FILE expires in $DAYS_LEFT days!"
exit 1
else
echo "Certificate $CERT_FILE is valid for $DAYS_LEFT more days."
exit 0
fi
For production environments, consider dedicated certificate monitoring tools or services that can alert you well before certificates expire.
Private Key Management
Proper management of private keys is critical for security. OpenSSL provides comprehensive tools for generating, protecting, analyzing, and converting private keys for various applications.
Generating Private Keys
OpenSSL supports multiple key types and encryption algorithms to meet different security requirements:
# Generate an RSA private key (2048 bits - minimum recommended)
openssl genrsa -out private_key_2048.key 2048
# Generate an RSA private key (4096 bits - higher security)
openssl genrsa -out private_key_4096.key 4096
# Generate an RSA private key with AES-256 encryption (password-protected)
openssl genrsa -aes256 -out encrypted_private.key 4096
# Generate an EC private key (using prime256v1 curve - NIST P-256)
openssl ecparam -name prime256v1 -genkey -noout -out ec_private.key
# Generate an EC private key with encryption
openssl ecparam -name prime256v1 -genkey | openssl ec -aes256 -out ec_encrypted.key
# Generate an EC private key with explicit curve parameters (for specialized applications)
openssl ecparam -name secp384r1 -genkey -param_enc explicit -out ec_explicit.key
# Generate an Ed25519 key (OpenSSL 1.1.1+) - modern, high-performance
openssl genpkey -algorithm ED25519 -out ed25519_private.key
# Generate an Ed25519 key with encryption
openssl genpkey -algorithm ED25519 -out ed25519_encrypted.key -aes-256-cbc
Key Types and Algorithms
When selecting a key type, consider security requirements, performance needs, and compatibility:
Key Type | Command | Bit Size | Security Level | Use Case | Compatibility |
---|---|---|---|---|---|
RSA-2048 | genrsa | 2048 | Standard | General purpose | Universal |
RSA-3072 | genrsa | 3072 | High | Long-term security | Universal |
RSA-4096 | genrsa | 4096 | Very High | Critical infrastructure | Universal but slower |
ECC (P-256) | ecparam | 256 | High | Mobile/IoT, limited CPU | Modern systems |
ECC (P-384) | ecparam | 384 | Very High | Government/Financial | Modern systems |
Ed25519 | genpkey | 256 | High | High-performance signing | Newer systems only |
X25519 | genpkey | 256 | High | Key exchange (ECDH) | Modern TLS 1.3 |
Ed448 | genpkey | 448 | Very High | High-security signing | Newest systems only |
X448 | genpkey | 448 | Very High | High-security key exchange | Newest systems only |
Note
Security equivalence: RSA-2048 ≈ ECC-224, RSA-3072 ≈ ECC-256, RSA-7680 ≈ ECC-384, RSA-15360 ≈ ECC-521. ECC provides equivalent security with smaller keys and better performance.
# Generate Ed25519 key (OpenSSL 1.1.1+)
openssl genpkey -algorithm ED25519 -out ed25519_key.pem
# View Ed25519 key details
openssl pkey -in ed25519_key.pem -text -noout
# Generate X25519 key for ECDH key exchange
openssl genpkey -algorithm X25519 -out x25519_key.pem
# Extract public key from Ed25519 private key
openssl pkey -in ed25519_key.pem -pubout -out ed25519_public.pem
# Generate Ed448 key (OpenSSL 1.1.1+)
openssl genpkey -algorithm ED448 -out ed448_key.pem
# Generate X448 key for high-security key exchange
openssl genpkey -algorithm X448 -out x448_key.pem
Working with Encrypted Keys
Password protection adds an essential security layer to private keys:
# Encrypt an existing unprotected private key
openssl rsa -in unencrypted.key -aes256 -out encrypted.key
# Decrypt an encrypted private key (removes password protection - use with caution)
openssl rsa -in encrypted.key -out decrypted.key
# Change the password on an already-encrypted key
openssl rsa -in encrypted.key -aes256 -out new_encrypted.key
# Check if a key is encrypted
cat private.key | grep -i "ENCRYPTED"
# Or try to read without password:
openssl rsa -in private.key -noout -check 2>/dev/null || echo "Key is encrypted"
# Create a strong password for key encryption
openssl rand -base64 48
# Create a protected key with PKCS#8 and stronger key derivation (more secure)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 |
openssl pkcs8 -topk8 -v2 aes-256-cbc -iter 100000 -out strong_encrypted.key
Verifying and Analyzing Keys
Always verify the integrity and properties of private keys:
# Check a private key's validity
openssl rsa -in private.key -check -noout
# Display detailed private key components (modulus, exponents, etc.)
openssl rsa -in private.key -text -noout
# Show just the key's modulus (useful for key matching)
openssl rsa -in private.key -noout -modulus
# Get key size in bits
openssl rsa -in private.key -text -noout | grep "Private-Key"
# Verify an EC key
openssl ec -in ec_private.key -check -noout
# Check EC key details and curve
openssl ec -in ec_private.key -text -noout | grep "ASN1 OID"
# Verify if a private key matches a certificate (hashes should match)
echo "Certificate: $(openssl x509 -noout -modulus -in certificate.crt | openssl md5)"
echo "Private Key: $(openssl rsa -noout -modulus -in private.key | openssl md5)"
# Verify if a private key matches a CSR
echo "CSR: $(openssl req -noout -modulus -in request.csr | openssl md5)"
echo "Private Key: $(openssl rsa -noout -modulus -in private.key | openssl md5)"
Extracting Public Keys
Extract public keys for various purposes:
# Extract public key from private RSA key
openssl rsa -in private.key -pubout -out public.key
# Extract public key from private EC key
openssl ec -in ec_private.key -pubout -out ec_public.key
# Extract public key from private Ed25519 key
openssl pkey -in ed25519_private.key -pubout -out ed25519_public.key
# Extract public key from certificate
openssl x509 -in certificate.crt -pubkey -noout > public_from_cert.key
# Extract public key from CSR
openssl req -in request.csr -pubkey -noout > public_from_csr.key
# View public key details
openssl pkey -in public.key -pubin -text -noout
# Calculate public key fingerprint (for SSH or verification)
openssl pkey -in public.key -pubin -outform DER | openssl dgst -sha256 -binary | openssl base64
Secure Random Number Generation
Cryptographic operations rely on strong random number generation. OpenSSL provides tools for generating and working with random data:
# Generate random bytes (binary output)
openssl rand 32
# Generate random bytes (base64 encoded)
openssl rand -base64 32
# Generate random bytes (hex encoded)
openssl rand -hex 32
# Generate random password with specific character set
openssl rand -base64 15 | tr -dc 'a-zA-Z0-9!@#$%^&*()_+?><~'
# Create a random symmetric key (e.g., for AES-256)
openssl rand -out aes_key.bin 32
# Generate a random initialization vector (IV)
openssl rand -out iv.bin 16
# Test randomness quality
openssl rand 1000000 | openssl dgst -sha256
# Use pseudorandom data for testing (NOT for production)
openssl rand -engine rdrand -out test_random.bin 32
Important
Secure random number generation is critical for cryptographic security. Always ensure:
- Your system has sufficient entropy sources
- Use hardware-based random number generators when available
- Never use predictable seeds or weak PRNGs for key generation
- For virtual machines, consider entropy augmentation solutions
- Test your random number generator quality with tools like
rngtest
orent
Converting Between Key Formats
Convert keys between formats for compatibility with different systems:
# Convert traditional RSA key to PKCS#8 format (modern standard)
openssl pkcs8 -topk8 -nocrypt -in private.key -out private.p8
# Convert to PKCS#8 with strong encryption (recommended for storage)
openssl pkcs8 -topk8 -in private.key -out encrypted.p8 -v2 aes-256-cbc -iter 100000
# Convert PKCS#8 back to traditional format
openssl rsa -in private.p8 -out traditional.key
# Convert PEM to DER format (binary)
openssl rsa -in private.key -outform DER -out private.der
# Convert DER to PEM format (text)
openssl rsa -in private.der -inform DER -out private.pem
# Convert private key to PKCS#12 format (with certificate)
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt -certfile ca-chain.crt
# Extract private key from PKCS#12
openssl pkcs12 -in certificate.p12 -nocerts -out private_from_p12.key
# Convert EC key to traditional PEM format
openssl ec -in ec_key.pem -out ec_traditional.pem
# Convert SSH public key to OpenSSL format (if you have the SSH public key)
ssh-keygen -e -m PKCS8 -f id_rsa.pub > ssh_key_openssl.pem
Enhanced Key Security Practices
Implement these additional measures for sensitive key material:
# Set proper file permissions
chmod 600 private.key # Owner read/write only
chmod 400 encrypted.key # Owner read only (good for backup copies)
# Verify file permissions
stat -c "%a %n" private.key
# Create a secure backup of critical keys
tar -cz -f keys-backup.tar.gz *.key
openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 -in keys-backup.tar.gz -out keys-backup.enc
# Create key usage audit log
echo "$(date) - $(whoami) - Generated key: $(openssl rsa -in private.key -noout -modulus | openssl md5)" >> key_audit.log
# Use hardware security if available (example for YubiKey)
yubico-piv-tool -s 9c -a generate -o public.pem
# Securely delete key material when no longer needed
shred -u -z -n 3 unneeded_key.pem
Important
For critical infrastructure and high-security environments:
- Consider hardware security modules (HSMs) instead of file-based keys
- Implement key custodian procedures with multi-person access controls
- Establish formal key management policies including rotation schedules
- Maintain an inventory of all cryptographic keys with owners and purposes
- Perform regular key security audits
CSR Creation and Management
Certificate Signing Requests (CSRs) are essential for requesting certificates from Certificate Authorities (CAs). They contain your public key and identifying information without including your private key.
Creating a Certificate Signing Request (CSR)
# Generate a new private key and CSR (interactive mode)
openssl req -new -newkey rsa:4096 -nodes -keyout private.key -out request.csr
# Generate a CSR from an existing private key (interactive mode)
openssl req -new -key private.key -out request.csr
# Generate a CSR with subject information (non-interactive)
openssl req -new -key private.key -out request.csr \
-subj "/C=US/ST=State/L=City/O=Organization/OU=Department/CN=example.com"
# Generate a CSR with SHA-256 signature (recommended)
openssl req -new -key private.key -out request.csr -sha256 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
# Generate a CSR with modern parameters
openssl req -new -key private.key -out request.csr -sha256 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com" \
-addext "keyUsage=digitalSignature,keyEncipherment" \
-addext "extendedKeyUsage=serverAuth"
Tip
Important fields in subject information:
- C: Country (2-letter code, e.g., US, GB, DE)
- ST: State/Province
- L: Locality/City
- O: Organization
- OU: Organizational Unit (department)
- CN: Common Name (your domain name)
- emailAddress: Administrative contact
Adding Subject Alternative Names (SANs)
Most certificate authorities require SANs in CSRs for modern TLS certificates:
# Create a configuration file for SAN
cat > san.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
OU = Department
CN = example.com
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = *.example.com
IP.1 = 192.168.1.1
EOF
# Generate a CSR with SANs
openssl req -new -key private.key -out san_request.csr -config san.conf
# Generate a CSR and private key in one command with SANs
openssl req -new -newkey rsa:4096 -nodes -keyout private.key \
-out san_request.csr -config san.conf
Important
Most commercial CAs have specific requirements for CSRs:
- Using strong key sizes (2048 bits minimum, 4096 bits recommended)
- Including all domains in SANs (even the primary domain)
- Using business validation information in the Organization field
- Using SHA-256 signatures (not SHA-1)
Verifying a CSR
Always verify your CSR before submitting it to a CA:
# View complete CSR information
openssl req -in request.csr -text -noout
# Verify CSR signature (checks if the CSR is valid)
openssl req -in request.csr -verify -noout
# View CSR subject information
openssl req -in request.csr -subject -noout
# Check SANs in the CSR
openssl req -in request.csr -text -noout | grep -A 1 "Subject Alternative Name"
# Extract the public key from a CSR
openssl req -in request.csr -noout -pubkey > pubkey.pem
# Check key size and algorithm
openssl req -in request.csr -noout -text | grep "Public-Key"
CSR Submission Process
The typical process for obtaining a certificate from a commercial CA:
- Generate a CSR with appropriate information and SANs
- Submit the CSR to your chosen Certificate Authority
- Complete domain validation (DV), organization validation (OV), or extended validation (EV)
- Receive and install the signed certificate and any intermediate certificates
# Domain validation methods typically include:
# - Email validation (to admin@, webmaster@, etc.)
# - DNS TXT record validation
# - HTTP file validation (place a file on your web server)
# Example of HTTP file validation
# 1. CA provides you with a token value
# 2. Create a file at http://example.com/.well-known/pki-validation/token.txt
# 3. CA verifies the file to prove domain ownership
CSR Templates for Different Purposes
Different certificate types require different CSR configurations:
Web Server (TLS/SSL) Certificate CSR
cat > web_server.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = example.com
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF
Email (S/MIME) Certificate CSR
cat > email.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = John Doe
emailAddress = john.doe@example.com
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = emailProtection, clientAuth
EOF
Code Signing Certificate CSR
cat > code_signing.conf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = Organization Code Signing
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = codeSigning
EOF
These templates can be used with the standard CSR generation command:
openssl req -new -newkey rsa:4096 -nodes -keyout private.key -out request.csr -config template.conf
Certificate Conversions
Understanding certificate formats and conversion between them is essential for compatibility with different systems and applications.
Common Certificate Formats Overview
Format | File Extensions | Description | Typical Use Cases |
---|---|---|---|
PEM | .pem, .crt, .cer, .key | Base64 encoded with header/footer | Web servers, OpenSSL |
DER | .der, .cer | Binary format | Java applications, Windows |
PKCS#7 | .p7b, .p7c | Certificate collection | Windows, Java Keystores |
PKCS#12 | .pfx, .p12 | Private key & certificates | Windows, macOS, browsers |
JKS | .jks | Java KeyStore | Java applications |
Converting Between Formats
# PEM to DER format
openssl x509 -in certificate.pem -outform der -out certificate.der
# DER to PEM format
openssl x509 -in certificate.der -inform der -outform pem -out certificate.pem
# PEM to PKCS#12 (PFX) format (includes private key and chain)
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile ca-chain.crt -name "Friendly Name"
# PEM to PKCS#12 without encryption (for automated processes)
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile ca-chain.crt -nodes -passout pass:
# PKCS#12 (PFX) to PEM format (extracts all certificates and private key)
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes
# Extract only the private key from PKCS#12
openssl pkcs12 -in certificate.pfx -nocerts -out private.key -nodes
# Extract only the certificates from PKCS#12
openssl pkcs12 -in certificate.pfx -nokeys -out certificate.crt
# Extract specific certificate from PKCS#12 by friendly name
openssl pkcs12 -in certificate.pfx -nokeys -out certificate.crt -name "Friendly Name"
# Convert PEM certificate and key to Java KeyStore (JKS)
# (requires keytool from Java JDK)
# First convert to PKCS#12
openssl pkcs12 -export -out temp.p12 -inkey private.key -in certificate.crt -name "server-cert"
# Then convert PKCS#12 to JKS
keytool -importkeystore -srckeystore temp.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS
Note
The -nodes
parameter (stands for "no DES") prevents encryption of the output. For security, use encryption when storing private keys.
Working with PKCS#7 and Certificate Bundles
PKCS#7 files typically contain certificates without private keys and are often used for certificate chains:
# Create a PKCS#7 file from certificates
openssl crl2pkcs7 -nocrl -certfile certificate.crt -certfile intermediate.crt -out certificate.p7b
# Extract certificates from PKCS#7 to PEM
openssl pkcs7 -in certificate.p7b -print_certs -out certificate.pem
# Create a certificate bundle/chain (concatenation)
cat certificate.crt intermediate.crt rootca.crt > fullchain.pem
# Split a PEM file containing multiple certificates
awk 'BEGIN {c=0} /BEGIN CERT/{c++} {print > "cert." c ".pem"}' < combined.pem
# Check how many certificates are in a bundle
grep -c "BEGIN CERTIFICATE" fullchain.pem
# View all certificates in a bundle
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
Platform-Specific Formats and Conversions
Different platforms and applications may require specific certificate formats:
# For Apache: PEM format with separate key and certificate files
# certificate.crt - The server certificate
# private.key - The private key
# ca-chain.crt - The CA certificate chain
# For Nginx: PEM format with separate key and certificate files
# certificate.crt - The server certificate
# private.key - The private key
# ca-chain.crt - The CA certificate chain
# For HAProxy: PEM format with combined key and certificates
cat private.key certificate.crt ca-chain.crt > haproxy.pem
# For IIS: PKCS#12 (PFX) format
openssl pkcs12 -export -out iis.pfx -inkey private.key -in certificate.crt -certfile ca-chain.crt
# For Tomcat: PKCS#12 or JKS format
keytool -importkeystore -srckeystore certificate.pfx -srcstoretype PKCS12 -destkeystore tomcat.jks -deststoretype JKS
SSL/TLS Testing
OpenSSL provides powerful tools for testing and troubleshooting SSL/TLS connections. These commands help you verify server configurations, identify misconfigurations, and diagnose connectivity issues.
Testing SSL/TLS Connections
The s_client
command creates an SSL/TLS client connection to a server, showing details about the handshake, certificates, and protocols:
# Basic connection test (HTTPS)
openssl s_client -connect example.com:443
# Test with Server Name Indication (SNI) - important for virtual hosts
openssl s_client -connect example.com:443 -servername example.com
# Display the full certificate chain
openssl s_client -connect example.com:443 -showcerts
# Save server certificate to a file
openssl s_client -connect example.com:443 -showcerts </dev/null | \
sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > certificate.pem
# Test a specific TLS version
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
# Force TLSv1.3 only
openssl s_client -connect example.com:443 -tls1_3 -no_tls1_2 -no_tls1_1 -no_tls1
# Test STARTTLS for protocols like SMTP, POP3, IMAP, FTP
openssl s_client -connect mail.example.com:25 -starttls smtp
openssl s_client -connect mail.example.com:110 -starttls pop3
openssl s_client -connect mail.example.com:143 -starttls imap
# Check for certificate expiration
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
# Bypass DNS resolution with IP connection
openssl s_client -connect 192.168.1.1:443 -servername example.com
# View all handshake details including session tickets and session resumption
openssl s_client -connect example.com:443 -state -debug
Analyzing Connection Security
Evaluate various security aspects of an SSL/TLS connection:
# Check for SSL renegotiation support (security vulnerability)
openssl s_client -connect example.com:443 -reconnect
# Check for session resumption capability
openssl s_client -connect example.com:443 -reconnect -no_ticket
# Verify OCSP stapling
openssl s_client -connect example.com:443 -status
# Check which cipher suites a server supports
for cipher in $(openssl ciphers 'ALL:eNULL' | tr ':' ' '); do
echo -n "Testing $cipher... "
result=$(openssl s_client -connect example.com:443 -cipher "$cipher" -servername example.com </dev/null 2>&1)
if [[ "$result" =~ "Cipher is $cipher" || "$result" =~ "Cipher :" ]]; then
echo "Supported"
else
echo "Not supported"
fi
done
# Test for specific vulnerabilities
# Heartbleed
openssl s_client -connect example.com:443 -tlsextdebug 2>&1 | grep 'server extension "heartbeat"'
# BEAST vulnerability (CBC ciphers in TLSv1.0)
openssl s_client -connect example.com:443 -tls1 -cipher 'ECDHE-RSA-AES128-SHA:AES128-SHA'
# POODLE vulnerability (SSLv3)
openssl s_client -connect example.com:443 -ssl3
# FREAK vulnerability (export ciphers)
openssl s_client -connect example.com:443 -cipher 'EXPORT'
Server Setup and Testing
OpenSSL also provides an s_server
command to set up a test SSL/TLS server:
# Set up a simple HTTPS server for testing (on port 4433)
openssl s_server -cert server.crt -key server.key -accept 4433 -www
# Set up a server with specific TLS version and ciphers
openssl s_server -cert server.crt -key server.key -accept 4433 -tls1_2 -cipher 'HIGH:!aNULL:!MD5'
# Test client certificate authentication
openssl s_server -cert server.crt -key server.key -accept 4433 -verify 1 -CAfile ca.crt
# Connect to a test server with a client certificate
openssl s_client -connect localhost:4433 -cert client.crt -key client.key -CAfile ca.crt
Practical Security Assessments
Here are some practical security checks for production servers:
# 1. Check supported protocols (prefer TLS 1.2+ only)
echo "Testing TLS 1.3:"
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>/dev/null | grep Protocol
echo "Testing TLS 1.2:"
openssl s_client -connect example.com:443 -tls1_2 </dev/null 2>/dev/null | grep Protocol
echo "Testing TLS 1.1 (deprecated):"
openssl s_client -connect example.com:443 -tls1_1 </dev/null 2>/dev/null | grep Protocol
echo "Testing TLS 1.0 (deprecated):"
openssl s_client -connect example.com:443 -tls1 </dev/null 2>/dev/null | grep Protocol
echo "Testing SSL 3.0 (insecure):"
openssl s_client -connect example.com:443 -ssl3 </dev/null 2>/dev/null | grep Protocol
# 2. Check certificate information
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | \
openssl x509 -noout -text | grep -A 2 Validity
# 3. Check cipher order (preference)
openssl s_client -connect example.com:443 -cipher "ALL:eNULL" -servername example.com </dev/null 2>/dev/null | \
grep "Cipher :"
Tip
For comprehensive security testing, consider specialized tools like SSLyze, testssl.sh, or Qualys SSL Labs (online).
Additional Security Checks
Check for specific vulnerabilities and security features:
# Check for TLS compression (CRIME vulnerability)
openssl s_client -connect example.com:443 -compress
# Check for Heartbleed vulnerability (OpenSSL 1.0.1 through 1.0.1f)
openssl s_client -connect example.com:443 -tlsextdebug 2>&1 | grep 'server extension "heartbeat"'
# Check support for TLS extensions
openssl s_client -connect example.com:443 -tlsextdebug
# Check for secure renegotiation
openssl s_client -connect example.com:443 | grep "Secure Renegotiation"
# Check for perfect forward secrecy
openssl s_client -connect example.com:443 | grep "Server Temp Key"
Testing SSL/TLS Ciphers
Evaluate cipher support and security configuration:
# Check which cipher is used for a connection
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'
# List all supported ciphers by your OpenSSL installation
openssl ciphers -v 'ALL:eNULL'
# List only strong ciphers
openssl ciphers -v 'HIGH:!aNULL:!eNULL:!3DES:!DES:!RC4:!MD5:!PSK:!SRP:!DSS'
# List elliptic curve ciphers only
openssl ciphers -v 'ECDHE:ECDH:ECDSA'
# List TLS 1.3 cipher suites (OpenSSL 1.1.1+)
openssl ciphers -v -tls1_3
# List all ciphers in order of strength (from strongest to weakest)
openssl ciphers -v 'ALL:@STRENGTH'
# Check if a server supports a specific cipher
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'
# If the connection succeeds, the server supports this cipher
# Test TLS 1.3 support and cipher suites
openssl s_client -connect example.com:443 -tls1_3
# Test if server prefers its own cipher order (more secure)
openssl s_client -connect example.com:443 2>&1 | grep "Server Temp Key"
Modern TLS 1.3 Configurations
TLS 1.3 (introduced in OpenSSL 1.1.1+) brings significant security and performance improvements:
# Check if OpenSSL supports TLS 1.3
openssl version
openssl ciphers -v | grep TLSv1.3
# Test TLS 1.3 connection
openssl s_client -connect example.com:443 -tls1_3
# Test TLS 1.3 with specific cipher suite
openssl s_client -connect example.com:443 -tls1_3 -ciphersuites TLS_AES_256_GCM_SHA384
# View TLS 1.3 handshake details
openssl s_client -connect example.com:443 -tls1_3 -msg -state
# List supported TLS 1.3 cipher suites
openssl ciphers -v -tls1_3
# Test TLS 1.3 0-RTT (Early Data) feature
echo "GET / HTTP/1.1" > request.txt
openssl s_client -connect example.com:443 -tls1_3 -sess_out session.pem
openssl s_client -connect example.com:443 -tls1_3 -sess_in session.pem -early_data request.txt
Key differences in TLS 1.3:
- Simplified Handshake: Faster connections with fewer round-trips
- Improved Privacy: Encrypts more of the handshake
- Removed Legacy Algorithms: Eliminates all known vulnerable cryptographic algorithms
- Forward Secrecy by Default: All TLS 1.3 cipher suites provide perfect forward secrecy
- Standard Cipher Suites: Only 5 cipher suites, all considered secure
Tip
For production servers, consider supporting only TLS 1.2 and TLS 1.3 with strong cipher suites. TLS 1.0 and 1.1 are deprecated and considered insecure.
Creating Test Servers
You can also create a simple test server to verify client connections:
# Create a self-signed certificate for testing
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes \
-subj "/CN=localhost"
# Start a simple SSL/TLS server on port 4433
openssl s_server -key server.key -cert server.crt -accept 4433 -www
# Connect to your test server with a client
openssl s_client -connect localhost:4433
Advanced Testing and Diagnostics
# Check SSL/TLS session parameters and ticket information
openssl s_client -connect example.com:443 -status -tlsextdebug
# Check OCSP stapling support
openssl s_client -connect example.com:443 -status | grep -A 10 "OCSP response"
# Test mutual TLS authentication (client certificate)
openssl s_client -connect example.com:443 -cert client.crt -key client.key
# Capture detailed handshake timing
openssl s_client -connect example.com:443 -debug -msg -state -time
# Validate certificate against Mozilla's included CA list
openssl s_client -connect example.com:443 -CApath /etc/ssl/certs
# Test TLS protocol version negotiation (downgrade attack protection)
openssl s_client -connect example.com:443 -no_tls1_3
Interpreting Connection Results
When using s_client
, look for these key indicators:
- Verify return code: Should be
0 (ok)
if the certificate validates properly - Protocol version: Should be TLSv1.2 or TLSv1.3 for modern security
- Cipher: Should use modern algorithms (ECDHE, AES-GCM, ChaCha20)
- Handshake: Check for successful completion
- Certificate chain: Verify all certificates in the chain are present
Example of a secure connection:
Protocol: TLSv1.3
Cipher: TLS_AES_256_GCM_SHA384
Verification: OK
Secure Renegotiation: supported
Server Temp Key: X25519, 253 bits
Advanced Operations
This section covers specialized operations for advanced users and security professionals.
Symmetric Encryption and Data Protection
OpenSSL provides robust tools for encrypting and protecting sensitive data using symmetric ciphers:
# Encrypt a file with AES-256-CBC (password-based)
openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.bin -pbkdf2
# Decrypt the file
openssl enc -aes-256-cbc -d -in encrypted.bin -out decrypted.txt -pbkdf2
# Encrypt with specific iteration count (more secure)
openssl enc -aes-256-cbc -salt -in plaintext.txt -out encrypted.bin -pbkdf2 -iter 100000
# Encrypt with a key file instead of password
openssl rand -out key.bin 32 # Generate 256-bit key
openssl enc -aes-256-cbc -in plaintext.txt -out encrypted.bin -kfile key.bin
# Use authenticated encryption (GCM mode) - OpenSSL 1.1.0+
openssl enc -aes-256-gcm -in plaintext.txt -out encrypted.bin -pbkdf2 -iter 100000
# Generate a random key and IV and save them
openssl rand -out key.bin 32
openssl rand -out iv.bin 16
openssl enc -aes-256-cbc -in plaintext.txt -out encrypted.bin -K $(xxd -p -c 64 key.bin) -iv $(xxd -p -c 32 iv.bin)
# List all available encryption algorithms
openssl enc -list
# Calculate message digest (hash)
openssl dgst -sha256 -out hash.txt plaintext.txt
# Create a digital signature of a file using a private key
openssl dgst -sha256 -sign private.key -out signature.bin document.txt
# Verify a signature using the public key
openssl dgst -sha256 -verify public.key -signature signature.bin document.txt
Tip
Best practices for symmetric encryption:
- Use AES-256-GCM when possible (authenticated encryption)
- Use PBKDF2 with high iteration counts (100,000+) for password-based encryption
- Store IVs with ciphertext (they don't need to be secret)
- Never reuse the same key+IV combination
- Consider envelope encryption (encrypting data keys with master keys)
Working with OCSP (Online Certificate Status Protocol)
OCSP provides real-time certificate revocation status checking:
# Generate an OCSP request
openssl ocsp -issuer ca.crt -cert certificate.crt -reqout ocsp_request.der
# Send an OCSP request to a responder
openssl ocsp -issuer ca.crt -cert certificate.crt -url http://ocsp.example.com -resp_text
# Send OCSP request to a responder and verify the response
openssl ocsp -issuer ca.crt -cert certificate.crt -url http://ocsp.example.com -verify_other ca.crt
# Create a simple OCSP responder (for testing)
openssl ocsp -index ca/index.txt -port 8888 -rsigner ca.crt -rkey ca.key -CA ca.crt -text
# Setup OCSP stapling on a server (embed OCSP response in TLS handshake)
# 1. Get an OCSP response
openssl ocsp -issuer intermediate.crt -cert server.crt -url http://ocsp.example.com -respout ocsp.der
# 2. Configure the web server to use this response (specific to each server type)
Certificate Transparency (CT) Logs
Certificate Transparency is a security framework for monitoring and auditing certificates:
# Extract SCTs (Signed Certificate Timestamps) from a certificate
openssl x509 -in certificate.crt -noout -text | grep -A 20 "CT Precertificate SCTs"
# Verify SCT data
# Typically requires specialized tools like ct-verifier
Time Stamping
Create cryptographically verifiable timestamps for documents and code:
# Create a timestamp request
openssl ts -query -data file.txt -no_nonce -out request.tsq
# Send the request to a timestamp server
curl -H "Content-Type: application/timestamp-query" \
--data-binary @request.tsq \
https://timestamp.example.com > response.tsr
# Verify a timestamp response
openssl ts -verify -data file.txt -in response.tsr -CAfile tsaca.crt
Cryptographic Performance Testing
Benchmark cryptographic operations to evaluate system performance:
# Test RSA signing performance
openssl speed rsa
# Test specific RSA key sizes
openssl speed rsa2048 rsa4096
# Test ECC performance
openssl speed ecdsap256
# Test symmetric cipher performance
openssl speed -evp aes-256-gcm aes-256-cbc chacha20-poly1305
# Test hash function performance
openssl speed sha256 sha512
# Test performance on multiple sizes
openssl speed -bytes 16 -bytes 64 -bytes 1024 -bytes 8192 aes-256-gcm
Hardware Security Module (HSM) Integration
For high-security environments, OpenSSL can work with HSMs:
# Using OpenSSL with PKCS#11 HSM (requires the engine to be installed)
openssl req -new -engine pkcs11 -keyform engine -key slot_0-label_key \
-out request.csr -config openssl.cnf
# List available engines
openssl engine -t -c
# Use a specific engine
openssl req -engine pkcs11 -new -key id_of_key -keyform engine -out req.pem
Working with Elliptic Curve Cryptography
ECC provides stronger security with smaller key sizes:
# Generate an EC private key using a named curve
openssl ecparam -name prime256v1 -genkey -noout -out ec_key.pem
# Convert EC key to PKCS#8 format with encryption
openssl pkcs8 -topk8 -in ec_key.pem -out ec_key_pkcs8.pem -encrypt
# List supported EC curves
openssl ecparam -list_curves
# Generate parameters for a specific curve
openssl ecparam -name secp384r1 -out secp384r1.pem
# Generate a CSR using an EC key
openssl req -new -key ec_key.pem -out ec_request.csr
# Create a self-signed cert with EC key
openssl req -new -x509 -key ec_key.pem -out ec_cert.pem -days 365
Troubleshooting
This section addresses common OpenSSL issues and their solutions.
Common Issues and Solutions
Certificate Verification Failures
# Check the entire certificate chain
openssl verify -verbose -CAfile ca_bundle.crt certificate.crt
# Inspect certificate information for errors
openssl x509 -in certificate.crt -text -noout
# Test if an intermediate certificate is missing
openssl verify -untrusted intermediate.crt -CAfile root.crt certificate.crt
# Validate certificate hostname
openssl x509 -in certificate.crt -noout -checkhost example.com
# Check certificate trust issues
openssl verify -CApath /etc/ssl/certs -verbose certificate.crt
Private Key Problems
# Check if a private key matches a certificate
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
# The outputs should match
# Check if a private key is valid
openssl rsa -check -in private.key
# Check if a private key is properly formatted
openssl rsa -in private.key -text -noout
# Fix a corrupted key (if in text format)
grep -v "^#" private.key > fixed_key.pem
CSR Validation Issues
# Verify CSR integrity
openssl req -verify -in request.csr -noout
# Check CSR contents
openssl req -text -noout -verify -in request.csr
# Fix a corrupted CSR (if in text format)
grep -v "^#" request.csr > fixed_csr.pem
Connectivity Problems
# Test basic connectivity to a server
openssl s_client -connect example.com:443 -servername example.com
# Test through a proxy (using nc as a CONNECT proxy)
nc -X connect -x proxy.example.com:8080 example.com 443 | openssl s_client -quiet -connect example.com:443
# Test with specific protocol version
openssl s_client -connect example.com:443 -tls1_2
# Bypass SNI restrictions
openssl s_client -connect IP_ADDRESS:443 -servername example.com
Diagnosing TLS Handshake Failures
TLS handshake failures are common but can be difficult to diagnose:
# Full debug output of handshake
openssl s_client -connect example.com:443 -debug -msg -state
# Check for supported cipher suites
openssl s_client -connect example.com:443 -cipher 'HIGH' -tls1_2
# Check for client certificate requirements
openssl s_client -connect example.com:443 -cert client.crt -key client.key
# Debug output with timing information
openssl s_client -connect example.com:443 -tls1_2 -debug -time -msg -state
Identifying and Fixing Expired Certificates
# Check certificate expiration
openssl x509 -enddate -noout -in certificate.crt
# Calculate days until expiration
echo "(" $(date -d "$(openssl x509 -enddate -noout -in certificate.crt | cut -d= -f2)" +%s) - $(date +%s) ")" / 86400 | bc
# Create a renewal CSR using the same key
openssl x509 -x509toreq -in certificate.crt -signkey private.key -out renewal.csr
Recommendations and Resources
Automating Certificate Management
Modern certificate management should be automated to reduce human error and ensure timely renewals:
# Example automated monitoring script
#!/bin/bash
CERT_DIR="/etc/ssl/certs"
DAYS_WARNING=30
EMAIL="admin@example.com"
LOG_FILE="/var/log/cert-monitor.log"
echo "Certificate check run on $(date)" >> $LOG_FILE
for cert in $CERT_DIR/*.crt; do
if [ ! -f "$cert" ]; then continue; fi
CERT_NAME=$(basename "$cert")
ENDDATE=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)
ENDDATE_EPOCH=$(date -d "$ENDDATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (ENDDATE_EPOCH - NOW_EPOCH) / 86400 ))
echo "Certificate $CERT_NAME expires in $DAYS_LEFT days" >> $LOG_FILE
if [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
echo "WARNING: Certificate $cert expires in $DAYS_LEFT days!" >> $LOG_FILE
echo "Certificate $CERT_NAME expires in $DAYS_LEFT days" | mail -s "Certificate Expiration Warning" $EMAIL
fi
done
For production environments, consider these automation tools:
Let's Encrypt Certbot: Automated certificate issuance and renewal for public domains
certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com
ACME.sh: Lightweight ACME client with broad DNS provider support
acme.sh --issue -d example.com -w /var/www/html
cert-manager: Kubernetes-native certificate management
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
HashiCorp Vault PKI: Enterprise-grade certificate management
vault write pki/root/generate/internal common_name="example.com" ttl=87600h
Tip
Implement these automation best practices:
- Set up monitoring with alerts well before expiration
- Test renewal processes before deployment
- Keep audit logs of all certificate operations
- Automate distribution of renewed certificates to all services
- Implement automated validation tests after renewal
Security Best Practices
Private Key Protection
- Use strong encryption for private keys
- Implement strict file permissions (0600 or more restrictive)
- Consider hardware security modules for critical keys
- Never share private keys or store them in unsecured locations
Certificate Management
- Implement automated certificate monitoring
- Set up alerts for expiring certificates (at least 30 days in advance)
- Maintain a certificate inventory
- Use appropriate key sizes (RSA 2048+ or ECC 256+)
Protocol and Cipher Configuration
- Disable SSLv3, TLSv1.0, and TLSv1.1
- Use only strong cipher suites
- Enable Perfect Forward Secrecy
- Implement HSTS for web servers
Operational Security
- Regularly audit certificate usage
- Implement proper revocation mechanisms
- Rotate keys periodically
- Follow the principle of least privilege for certificate issuance
Automation Best Practices
Automate certificate management to reduce human error:
# Example automated renewal check script
#!/bin/bash
CERT_DIR="/etc/ssl/certs"
DAYS_WARNING=30
for cert in $CERT_DIR/*.crt; do
ENDDATE=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)
ENDDATE_EPOCH=$(date -d "$ENDDATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (ENDDATE_EPOCH - NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
echo "WARNING: Certificate $cert expires in $DAYS_LEFT days!"
# Send email alert or trigger renewal process
fi
done
Useful Resources
- Official OpenSSL Documentation
- OpenSSL Cookbook
- Mozilla SSL Configuration Generator
- SSL Labs Server Test
- Let's Encrypt
# Check certificate policies and constraints
openssl x509 -in certificate.crt -text -noout | grep -A10 "X509v3 Name Constraints"
Debugging SSL/TLS Connections
# Enable full debugging output
openssl s_client -connect example.com:443 -debug
# Check handshake process
openssl s_client -connect example.com:443 -state
# Check TLS protocol version and cipher
openssl s_client -connect example.com:443 -tlsextdebug
Security Considerations
When working with OpenSSL and cryptographic operations, several security considerations should be kept in mind to avoid common pitfalls.
Known Vulnerabilities
OpenSSL has experienced several high-profile vulnerabilities. Awareness of these helps prevent security issues:
Vulnerability | Affected Versions | Description | Mitigation |
---|---|---|---|
Heartbleed (CVE-2014-0160) | 1.0.1 through 1.0.1f | Allows attackers to read memory from the server, potentially exposing private keys | Upgrade to 1.0.1g+ or 1.1.0+ |
POODLE (CVE-2014-3566) | All versions supporting SSLv3 | Padding Oracle attack allowing decryption of secure communications | Disable SSLv3 support |
FREAK (CVE-2015-0204) | Versions before 1.0.1k | Allows forced use of weak export-grade ciphers | Upgrade to 1.0.1k+ or 1.1.0+ |
Logjam (CVE-2015-4000) | All versions with weak DH parameters | Downgrade attack allowing MITM attacks | Use 2048+ bit DH parameters |
DROWN (CVE-2016-0800) | Versions supporting SSLv2 | Cross-protocol attack on TLS using SSLv2 | Disable SSLv2 support, upgrade to latest |
Secure Configuration Principles
- Disable Legacy Protocols: Explicitly disable SSLv2, SSLv3, TLSv1.0, and TLSv1.1 in production environments
- Use Strong Ciphers Only: Configure cipher suites to include only strong algorithms
- Implement Forward Secrecy: Prioritize ECDHE and DHE cipher suites
- Secure Renegotiation: Ensure only secure renegotiation is allowed
- OCSP Stapling: Enable OCSP stapling to enhance certificate validation privacy
Common Security Mistakes
- Weak Key Generation: Using insufficient key sizes (less than 2048-bit RSA or 256-bit ECC)
- Self-signed in Production: Using self-signed certificates in production environments
- Private Key Exposure: Inadequate protection of private keys, including:
- Insufficient file permissions
- Unencrypted private keys
- Storing keys in insecure locations
- Including private keys in backups or repositories
- Failure to Validate: Not properly validating certificate chains
- Certificate Lifespans: Using excessively long validity periods for certificates
- Ignoring Expiration: Not monitoring certificate expiration dates
- Weak Random Number Generation: Not ensuring sufficient entropy for key generation
Security-Focused Commands
# Generate a secure 4096-bit RSA key with strong encryption
openssl genrsa -aes256 -out secure_key.pem 4096
# Verify proper permissions on a key file
ls -la secure_key.pem
chmod 600 secure_key.pem
# Check OpenSSL PRNG state
openssl rand -writerand .rnd
# Verify a certificate hasn't been revoked (OCSP)
openssl ocsp -issuer ca.crt -cert cert.crt -text -url http://ocsp.example.com/
# Verify a certificate with CRL checking
openssl verify -crl_check -CAfile ca.crt -CRLfile revoked.crl cert.crt
# Create secure Diffie-Hellman parameters (2048+ bits)
openssl dhparam -out dhparams.pem 2048
Best Practices
Key and Certificate Management
Use Strong Keys:
- RSA: Minimum 2048-bit, prefer 4096-bit for CAs and high-security applications
- ECC: Minimum 256-bit curves (P-256/secp256r1 or better)
- EdDSA: Ed25519 for modern applications requiring high performance
Protect Private Keys:
- Always use strong password encryption for private keys (
-aes256
option) - Set restrictive file permissions:
chmod 600 private.key
- Consider hardware security modules (HSMs) for high-security environments
- Never store private keys in public repositories or unsecured backups
- Always use strong password encryption for private keys (
Certificate Chain Validation:
- Always include the complete certificate chain in server configurations
- Verify chain validity with
openssl verify -CAfile chain.pem cert.crt
- Include intermediate certificates when distributing end-entity certificates
Certificate Lifecycle Management:
- Implement automated certificate monitoring and renewal processes
- Set reasonable validity periods (90-398 days for public TLS certificates)
- Maintain a certificate inventory with expiration dates and renewal procedures
- Establish a documented revocation process
Naming and Organization:
- Use consistent, descriptive naming conventions for all files
- Organize certificates in a structured directory hierarchy
- Document certificate usage, ownership, and management responsibilities
Implementation Best Practices
Version Management:
- Stay current with the latest stable OpenSSL versions
- Subscribe to security announcements via openssl-announce
- Regularly check for security patches
Configuration Security:
- Use secure default configurations
- Disable legacy protocols (SSLv2, SSLv3, TLSv1.0, TLSv1.1)
- Prioritize forward secrecy cipher suites
- Configure secure cipher ordering with modern algorithms
Automation and Infrastructure:
- Use configuration management tools (Ansible, Chef, Puppet) for consistent deployment
- Implement certificate automation with tools like Certbot, cert-manager, or ACME clients
- Integrate certificate lifecycle management into CI/CD pipelines
- Consider certificate management services for enterprise environments
Testing and Validation:
- Regularly scan for expiring certificates
- Perform periodic security testing of TLS configurations
- Use tools like SSL Labs Server Test to validate configurations
- Implement automated testing in pre-production environments
Disaster Recovery:
- Maintain secure backups of CA certificates and private keys
- Document recovery procedures for compromised keys
- Create and test certificate revocation procedures
- Establish alternate validation methods in case of CA failure
Documentation Best Practices
Comprehensive Records:
- Maintain an inventory of all certificates with metadata
- Document procedures for certificate request, issuance, and renewal
- Keep records of certificate parameters, including key sizes and algorithms
Process Documentation:
- Create clear documentation for certificate operations
- Include step-by-step guides for common certificate tasks
- Document emergency procedures for certificate compromise