
OpenSSL Essentials – Working with SSL Certificates, Keys, and CSRs
OpenSSL is your Swiss Army knife for everything SSL/TLS-related, and mastering its essential operations for working with certificates, keys, and Certificate Signing Requests (CSRs) is fundamental for anyone dealing with secure communications. Whether you’re setting up HTTPS for a web server, securing API endpoints, or managing certificate renewals across your infrastructure, understanding how to generate, manipulate, and troubleshoot SSL components using OpenSSL will save you countless hours and prevent security mishaps that could compromise your applications.
How OpenSSL SSL Components Work
Before diving into commands, let’s clarify what we’re working with. SSL certificates operate in a public key infrastructure (PKI) ecosystem with three main components:
- Private Keys: Secret mathematical keys that prove ownership of a certificate and decrypt data
- Certificate Signing Requests (CSRs): Formal requests containing your public key and identity information, sent to Certificate Authorities
- SSL Certificates: Digital documents that bind your identity to your public key, signed by a trusted Certificate Authority
The workflow typically follows this pattern: generate private key → create CSR → submit to CA → receive signed certificate → deploy to server. OpenSSL handles all these operations through its command-line interface, which processes cryptographic operations using various algorithms like RSA, ECDSA, and different key sizes.
Essential OpenSSL Commands for Key Management
Let’s start with private key generation, the foundation of your SSL setup. Modern best practices recommend RSA 2048-bit minimum or ECDSA P-256 for better performance:
# Generate RSA 2048-bit private key
openssl genrsa -out private.key 2048
# Generate RSA 4096-bit private key (more secure, slower performance)
openssl genrsa -out private-4096.key 4096
# Generate ECDSA private key (faster, smaller, equally secure)
openssl ecparam -genkey -name prime256v1 -out ecdsa-private.key
# Generate encrypted private key (prompts for passphrase)
openssl genrsa -aes256 -out encrypted-private.key 2048
Key inspection and validation commands you’ll use constantly:
# View private key details
openssl rsa -in private.key -text -noout
# Verify private key integrity
openssl rsa -in private.key -check
# Remove passphrase from encrypted key
openssl rsa -in encrypted-private.key -out unencrypted-private.key
# Extract public key from private key
openssl rsa -in private.key -pubout -out public.key
Creating and Managing Certificate Signing Requests
CSRs contain the information that will appear in your final certificate. You can create them interactively or using configuration files for automation:
# Interactive CSR creation
openssl req -new -key private.key -out domain.csr
# Non-interactive CSR with command-line subject
openssl req -new -key private.key -out domain.csr -subj "/C=US/ST=California/L=San Francisco/O=Company Name/CN=example.com"
# CSR with Subject Alternative Names (SAN) for multiple domains
openssl req -new -key private.key -out domain.csr -config <(
cat <<EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C=US
ST=California
L=San Francisco
O=Company Name
CN=example.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=example.com
DNS.2=www.example.com
DNS.3=api.example.com
EOF
)
CSR validation and information extraction:
# View CSR details
openssl req -in domain.csr -text -noout
# Verify CSR signature
openssl req -in domain.csr -verify -noout
# Extract subject from CSR
openssl req -in domain.csr -subject -noout
# Check if private key matches CSR
diff <(openssl rsa -in private.key -pubout) <(openssl req -in domain.csr -pubkey -noout)
SSL Certificate Operations and Verification
Once you receive certificates from your CA, you'll need to verify, convert, and deploy them properly:
# View certificate details
openssl x509 -in certificate.crt -text -noout
# Check certificate expiration
openssl x509 -in certificate.crt -dates -noout
# Verify certificate against private key
diff <(openssl rsa -in private.key -pubout) <(openssl x509 -in certificate.crt -pubkey -noout)
# Verify certificate chain
openssl verify -CAfile ca-bundle.crt certificate.crt
# Check certificate against specific CA
openssl verify -CAfile intermediate.crt -untrusted ca-bundle.crt certificate.crt
Certificate format conversions (essential for different server types):
# 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
# Create PKCS#12 bundle (for Windows IIS, Java keystores)
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt -certfile ca-bundle.crt
# Extract certificate from PKCS#12
openssl pkcs12 -in certificate.p12 -clcerts -nokeys -out certificate.crt
# Extract private key from PKCS#12
openssl pkcs12 -in certificate.p12 -nocerts -out private.key
Real-World Use Cases and Automation
Here's a complete script for automated certificate deployment that many sysadmins use:
#!/bin/bash
# ssl-renewal.sh - Automated SSL certificate management
DOMAIN="example.com"
KEY_SIZE=2048
DAYS_BEFORE_EXPIRY=30
# Check if certificate expires soon
check_expiry() {
if openssl x509 -checkend $((DAYS_BEFORE_EXPIRY * 86400)) -noout -in "/etc/ssl/certs/${DOMAIN}.crt"; then
echo "Certificate valid for more than ${DAYS_BEFORE_EXPIRY} days"
exit 0
else
echo "Certificate expires soon, renewing..."
fi
}
# Generate new private key and CSR
generate_csr() {
openssl genrsa -out "/tmp/${DOMAIN}.key" $KEY_SIZE
openssl req -new -key "/tmp/${DOMAIN}.key" -out "/tmp/${DOMAIN}.csr" \
-subj "/C=US/ST=CA/L=SF/O=Company/CN=${DOMAIN}"
}
# Validate certificate installation
validate_cert() {
echo "Validating certificate installation..."
echo | openssl s_client -servername $DOMAIN -connect ${DOMAIN}:443 2>/dev/null | \
openssl x509 -noout -dates
}
check_expiry
generate_csr
# Submit CSR to your CA process here
validate_cert
For development environments, self-signed certificates are often needed:
# Generate self-signed certificate (valid for 365 days)
openssl req -x509 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt -days 365 -nodes \
-subj "/C=US/ST=Dev/L=Local/O=Development/CN=localhost"
# Self-signed with SAN for multiple local domains
openssl req -x509 -newkey rsa:2048 -keyout dev.key -out dev.crt -days 365 -nodes \
-extensions v3_req -config <(
cat <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
CN=localhost
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1=localhost
DNS.2=*.localhost
DNS.3=dev.local
IP.1=127.0.0.1
EOF
)
Performance Comparison: RSA vs ECDSA
Algorithm | Key Size | Security Level | Handshake Time | Certificate Size | CPU Usage |
---|---|---|---|---|---|
RSA | 2048-bit | 112-bit | ~3ms | ~1.2KB | High |
RSA | 4096-bit | 128-bit | ~12ms | ~1.8KB | Very High |
ECDSA | P-256 | 128-bit | ~1ms | ~0.3KB | Low |
ECDSA | P-384 | 192-bit | ~1.5ms | ~0.4KB | Medium |
Common Pitfalls and Troubleshooting
The most frequent issues you'll encounter and their solutions:
- Private key mismatch: Always verify your private key matches your certificate using the diff command shown earlier
- Missing intermediate certificates: Chain validation failures usually mean you need to include intermediate CA certificates in your bundle
- Incorrect certificate order: Certificate chains must be ordered from server certificate to root CA
- Expired certificates in chain: Check all certificates in your chain, not just the server certificate
Debug certificate chain issues with these commands:
# Test SSL connection and view full certificate chain
openssl s_client -showcerts -servername example.com -connect example.com:443
# Verify specific cipher support
openssl s_client -cipher ECDHE-RSA-AES256-GCM-SHA384 -connect example.com:443
# Check certificate transparency logs
openssl s_client -connect example.com:443 -servername example.com -status
Certificate chain validation script for production monitoring:
#!/bin/bash
# Check certificate chain validity
check_cert_chain() {
local domain=$1
local port=${2:-443}
echo "Checking certificate chain for ${domain}:${port}"
# Get certificate chain
certificates=$(echo | openssl s_client -servername $domain -connect ${domain}:${port} 2>/dev/null)
# Extract and verify each certificate
echo "$certificates" | openssl x509 -noout -subject -dates 2>/dev/null
# Check for common issues
if echo "$certificates" | grep -q "Verify return code: 0 (ok)"; then
echo "✓ Certificate chain is valid"
else
echo "✗ Certificate chain validation failed"
echo "$certificates" | grep "Verify return code"
fi
}
check_cert_chain "example.com"
Best Practices and Security Considerations
Following these practices will keep your SSL infrastructure secure and maintainable:
- Key storage: Store private keys with restrictive permissions (600) and never commit them to version control
- Key rotation: Generate new private keys for certificate renewals rather than reusing old ones
- Algorithm selection: Use ECDSA P-256 for new deployments unless legacy compatibility requires RSA
- Certificate transparency: Monitor CT logs for unauthorized certificates issued for your domains
- OCSP stapling: Enable OCSP stapling on your web servers to improve performance and privacy
For certificate monitoring and automation, consider integrating with tools like Certbot for Let's Encrypt certificates or CFSSL for internal CA management. The official OpenSSL documentation provides comprehensive references for advanced use cases and cryptographic details.
Remember that SSL certificate management is just one piece of a comprehensive security strategy. Regular monitoring, automated renewals, and proper key management practices will ensure your applications maintain secure communications without unexpected downtime from expired certificates.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.