Learn-skills.dev openssl-tls
OpenSSL commands for certificates, TLS debugging, and encryption. Use when user mentions "openssl", "ssl certificate", "tls", "self-signed cert", "certificate chain", "CSR", "private key", "cert expiry", "https debugging", "mTLS", "certificate authority", or any certificate/encryption task.
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/1mangesh1/dev-skills-collection/openssl-tls" ~/.claude/skills/neversight-learn-skills-dev-openssl-tls && rm -rf "$T"
manifest:
data/skills-md/1mangesh1/dev-skills-collection/openssl-tls/SKILL.mdsource content
OpenSSL & TLS
Certificates, TLS debugging, and encryption from the command line.
Generate Self-Signed Certificate
Quick (Dev/Local)
# One-liner: key + cert, valid 365 days openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \ -subj "/CN=localhost" # With SANs (needed for Chrome to accept it) openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" # EC key instead of RSA openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \ -keyout key.pem -out cert.pem -days 365 -nodes \ -subj "/CN=localhost"
Generate CSR and Private Key
# Generate private key openssl genrsa -out server.key 2048 # Generate CSR from existing key openssl req -new -key server.key -out server.csr \ -subj "/C=US/ST=California/L=SF/O=MyOrg/CN=example.com" # Generate key + CSR in one step openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr \ -subj "/C=US/ST=California/L=SF/O=MyOrg/CN=example.com" # CSR with SANs (create config file first) cat > san.cnf <<EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req [req_distinguished_name] CN = example.com [v3_req] subjectAltName = DNS:example.com,DNS:www.example.com,DNS:api.example.com EOF openssl req -new -key server.key -out server.csr -config san.cnf # Verify CSR contents openssl req -in server.csr -noout -text
View Certificate Details
# Full details openssl x509 -in cert.pem -noout -text # Just the subject and issuer openssl x509 -in cert.pem -noout -subject -issuer # Expiry dates openssl x509 -in cert.pem -noout -dates # SANs only openssl x509 -in cert.pem -noout -ext subjectAltName # Serial number openssl x509 -in cert.pem -noout -serial # Fingerprint openssl x509 -in cert.pem -noout -fingerprint -sha256 # From a remote server echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -text
Verify Certificate Chain
# Verify against system CA bundle openssl verify cert.pem # Verify against specific CA openssl verify -CAfile ca.pem cert.pem # Verify with intermediate chain openssl verify -CAfile ca.pem -untrusted intermediate.pem cert.pem # Show full chain from a server openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null
Test TLS Connection (s_client)
# Basic connection test openssl s_client -connect example.com:443 -servername example.com </dev/null # Show only cert summary echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -subject -issuer -dates # Force specific TLS version openssl s_client -connect example.com:443 -tls1_2 openssl s_client -connect example.com:443 -tls1_3 # Test with client cert (mTLS) openssl s_client -connect example.com:443 \ -cert client.pem -key client-key.pem -CAfile ca.pem # Check supported ciphers openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384' # STARTTLS for mail servers openssl s_client -connect mail.example.com:587 -starttls smtp openssl s_client -connect mail.example.com:993 -starttls imap
Check Cert Expiry
# Local cert file openssl x509 -in cert.pem -noout -enddate # Remote server echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -enddate # Days until expiry (Linux) expiry=$(openssl x509 -in cert.pem -noout -enddate | cut -d= -f2) echo $(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 )) days remaining # Days until expiry (macOS) expiry=$(openssl x509 -in cert.pem -noout -enddate | cut -d= -f2) echo $(( ($(date -j -f "%b %d %T %Y %Z" "$expiry" +%s) - $(date +%s)) / 86400 )) days remaining
Convert Between Formats
# PEM to DER openssl x509 -in cert.pem -outform DER -out cert.der # DER to PEM openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem # PEM to PKCS12 (PFX) -- combines cert + key openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem # With chain: openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -certfile chain.pem # PKCS12 to PEM (extract cert) openssl pkcs12 -in cert.pfx -clcerts -nokeys -out cert.pem # PKCS12 to PEM (extract key) openssl pkcs12 -in cert.pfx -nocerts -nodes -out key.pem # PKCS12 to PEM (everything) openssl pkcs12 -in cert.pfx -out everything.pem -nodes # Remove passphrase from key openssl rsa -in encrypted.key -out decrypted.key # Add passphrase to key openssl rsa -in decrypted.key -aes256 -out encrypted.key
Create a Local CA (Dev/Testing)
# 1. Generate CA private key openssl genrsa -out ca.key 4096 # 2. Create CA certificate openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem \ -subj "/C=US/ST=Dev/O=LocalCA/CN=Local Dev CA" # 3. Generate server key openssl genrsa -out server.key 2048 # 4. Create server CSR openssl req -new -key server.key -out server.csr \ -subj "/CN=myapp.local" # 5. Sign server cert with CA (with SANs) cat > server-ext.cnf <<EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment subjectAltName = DNS:myapp.local,DNS:*.myapp.local,IP:127.0.0.1 EOF openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out server.crt -days 825 -sha256 -extfile server-ext.cnf # 6. Trust the CA (macOS) sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.pem # 6. Trust the CA (Ubuntu/Debian) sudo cp ca.pem /usr/local/share/ca-certificates/local-dev-ca.crt sudo update-ca-certificates
mTLS Setup Basics
# Generate client key + cert signed by same CA openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr -subj "/CN=my-client" cat > client-ext.cnf <<EOF basicConstraints=CA:FALSE keyUsage = digitalSignature extendedKeyUsage = clientAuth EOF openssl x509 -req -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial \ -out client.crt -days 365 -sha256 -extfile client-ext.cnf # Test with curl curl --cert client.crt --key client.key --cacert ca.pem https://myapp.local:8443 # Test with openssl openssl s_client -connect myapp.local:8443 \ -cert client.crt -key client.key -CAfile ca.pem
Encrypt/Decrypt Files
# Symmetric encryption (AES-256-CBC, prompts for password) openssl enc -aes-256-cbc -salt -pbkdf2 -in secret.txt -out secret.enc openssl enc -aes-256-cbc -d -pbkdf2 -in secret.enc -out secret.txt # Encrypt with a key file openssl rand -out filekey.bin 32 openssl enc -aes-256-cbc -salt -pbkdf2 -in secret.txt -out secret.enc -pass file:filekey.bin openssl enc -aes-256-cbc -d -pbkdf2 -in secret.enc -out secret.txt -pass file:filekey.bin # Asymmetric: encrypt with public key, decrypt with private key openssl rsautl -encrypt -inkey public.pem -pubin -in secret.txt -out secret.enc openssl rsautl -decrypt -inkey private.pem -in secret.enc -out secret.txt
Generate Random Passwords/Keys
# Random hex string (32 bytes = 64 hex chars) openssl rand -hex 32 # Random base64 string openssl rand -base64 32 # Random bytes to file (for encryption keys) openssl rand -out keyfile.bin 32 # Quick password openssl rand -base64 18
Common Errors
certificate verify failed
The client does not trust the server cert. Either the CA is missing from the trust store or the chain is incomplete.
# Check what CA the cert needs openssl x509 -in cert.pem -noout -issuer # Test with explicit CA openssl s_client -connect host:443 -CAfile /path/to/ca-bundle.crt # Quick workaround (not for prod) curl -k https://... # or export NODE_TLS_REJECT_UNAUTHORIZED=0
unable to get local issuer certificate
The intermediate certificate is missing. The server needs to send the full chain.
# See what chain the server sends openssl s_client -connect host:443 -servername host -showcerts </dev/null 2>/dev/null # If intermediate is missing, concatenate it cat server.crt intermediate.crt > fullchain.crt
certificate has expired
# Confirm expiry echo | openssl s_client -connect host:443 2>/dev/null | openssl x509 -noout -dates
certificate is not yet valid
System clock is wrong, or the cert's notBefore is in the future.
# Check cert validity window openssl x509 -in cert.pem -noout -startdate -enddate # Check system time date -u
handshake failure / no shared cipher
TLS version or cipher mismatch between client and server.
# Check what the server supports openssl s_client -connect host:443 -tls1_2 openssl s_client -connect host:443 -tls1_3 # List available ciphers openssl ciphers -v 'ALL'
key values mismatch
The private key does not match the certificate.
# Compare modulus hashes -- they must match openssl x509 -in cert.pem -noout -modulus | openssl md5 openssl rsa -in key.pem -noout -modulus | openssl md5 openssl req -in csr.pem -noout -modulus | openssl md5