About us Guides Projects Contacts
Админка
please wait

OpenSSL is the industry-standard toolkit for TLS/SSL certificate management. Whether you're generating self-signed certificates for development, creating Certificate Signing Requests for production, or debugging certificate issues, OpenSSL is essential. This guide covers practical SSL/TLS certificate management from a senior developer's perspective.

Why Understand OpenSSL

Every developer should know OpenSSL because:

  1. Local Development: Self-signed certs for HTTPS testing
  2. Production Deployments: CSR generation for CA certificates
  3. Debugging: Verify certificates and connections
  4. Security Audits: Inspect certificate chains and expiration
  5. Automation: Script certificate management

Certificate Basics

Key Concepts

  • Private Key: Secret key; never share (.key)
  • Public Key: Derived from private key; safe to share
  • CSR: Certificate Signing Request, sent to CA (.csr)
  • Certificate: Signed public key with metadata (.crt, .pem)
  • CA: Certificate Authority, trusted signer
  • Chain: CA certificates linking to root CA

File Formats

ExtensionFormatContains
.pemBase64-encodedKeys, certs, or both
.crtUsually PEMCertificate only
.keyUsually PEMPrivate key only
.derBinaryCertificate
.p12/.pfxBinaryKey + cert bundle

Generate Self-Signed Certificates

Quick Self-Signed Certificate

# Generate the key and certificate in one command
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout server.key \
-out server.crt \
-days 365 \
-subj "/CN=localhost/O=Development/C=US"

With Subject Alternative Names (SAN)

Modern browsers require SAN for localhost:

# Create a config file
cat > san.cnf << 'EOF'
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = localhost
O = Development
C = US
[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = *.localhost
DNS.3 = myapp.local
IP.1 = 127.0.0.1
IP.2 = ::1
EOF
# Generate a certificate
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout server.key \
-out server.crt \
-days 365 \
-config san.cnf \
-extensions v3_req

Create a Local Certificate Authority

For development environments needing multiple certificates:

Step 1: Create CA

##!/bin/bash
OUTPUT_FOLDER=./certs
CA_DOMAIN="ca.local"
COMPANY="MyCompany"
COUNTRY="US"
mkdir -p $OUTPUT_FOLDER
# CA configuration
cat > $OUTPUT_FOLDER/ca.cnf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_req
prompt = no
encrypt_key = no
[req_distinguished_name]
CN = $CA_DOMAIN
O = $COMPANY
C = $COUNTRY
[v3_req]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = critical, CA:TRUE, pathlen:3
keyUsage = critical, cRLSign, keyCertSign
nsCertType = sslCA, emailCA
EOF
# Generate a CA certificate
openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -nodes \
-config $OUTPUT_FOLDER/ca.cnf \
-keyout $OUTPUT_FOLDER/ca.key \
-out $OUTPUT_FOLDER/ca.crt
echo "CA certificate created: $OUTPUT_FOLDER/ca.crt"

Step 2: Sign Certificates with CA

##!/bin/bash
DOMAIN=$1 # e.g., myapp.local
OUTPUT_FOLDER=./certs
# Server certificate configuration
cat > $OUTPUT_FOLDER/$DOMAIN.cnf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
x509_extensions = v3_ca
prompt = no
encrypt_key = no
default_bits = 4096
[req_distinguished_name]
CN = $DOMAIN
O = MyCompany
C = US
[v3_req]
basicConstraints = critical, CA:FALSE
[v3_ca]
basicConstraints = critical, CA:FALSE
authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:$DOMAIN, DNS:*.$DOMAIN
EOF
# Generate a CSR
openssl req -new -sha256 \
-keyout $OUTPUT_FOLDER/$DOMAIN.key \
-out $OUTPUT_FOLDER/$DOMAIN.csr \
-config $OUTPUT_FOLDER/$DOMAIN.cnf
# Sign with CA
openssl x509 -req -sha256 -days 365 \
-in $OUTPUT_FOLDER/$DOMAIN.csr \
-CA $OUTPUT_FOLDER/ca.crt \
-CAkey $OUTPUT_FOLDER/ca.key \
-CAcreateserial \
-out $OUTPUT_FOLDER/$DOMAIN.crt \
-extensions v3_ca \
-extfile $OUTPUT_FOLDER/$DOMAIN.cnf
# Create the full chain
cat $OUTPUT_FOLDER/$DOMAIN.crt $OUTPUT_FOLDER/ca.crt > $OUTPUT_FOLDER/$DOMAIN.fullchain.crt
# Clean up
rm $OUTPUT_FOLDER/$DOMAIN.csr $OUTPUT_FOLDER/$DOMAIN.cnf
echo "Certificate created: $OUTPUT_FOLDER/$DOMAIN.crt"

Step 3: Trust CA Certificate

Linux (CentOS/RHEL):

sudo cp ca.crt /etc/pki/ca-trust/source/anchors/myca.crt
sudo update-ca-trust

Linux (Ubuntu/Debian):

sudo cp ca.crt /usr/local/share/ca-certificates/myca.crt
sudo update-ca-certificates

Linux (openSUSE):

sudo cp ca.crt /usr/share/pki/trust/anchors/myca.crt
sudo update-ca-certificates --force

macOS:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.crt

Firefox: Navigate to about:preferences → Privacy & Security → View Certificates → Authorities → Import

Chrome: Navigate to chrome://settings/certificates → Authorities → Import

Generate CSR for Production

Create CSR for CA Signing

# Generate a private key
openssl genrsa -out example.com.key 4096
# Generate a CSR
openssl req -new -key example.com.key -out example.com.csr \
-subj "/CN=example.com/O=My Company/L=New York/ST=NY/C=US"
# Verify the CSR
openssl req -text -noout -verify -in example.com.csr

CSR with SAN

# Create a config
cat > csr.cnf << 'EOF'
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = example.com
O = My Company
L = New York
ST = NY
C = US
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
EOF
# Generate a CSR with SAN
openssl req -new -key example.com.key -out example.com.csr -config csr.cnf

Inspect Certificates

View Certificate Details

# View the local certificate
openssl x509 -text -noout -in certificate.crt
# View the remote certificate
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
openssl x509 -text -noout
# Check the expiration date
openssl x509 -enddate -noout -in certificate.crt
# View the certificate chain
openssl s_client -connect example.com:443 -showcerts

Verify Certificate and Key Match

# Compare modulus
openssl x509 -modulus -noout -in certificate.crt | md5sum
openssl rsa -modulus -noout -in private.key | md5sum
# Both should match

Check Certificate Chain

# Verify against CA
openssl verify -CAfile ca.crt server.crt
# Verify the full chain
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt

Convert Between Formats

PEM to DER

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

DER to PEM

openssl x509 -inform der -in certificate.der -out certificate.pem

Create PKCS12 Bundle

# Combine the key and cert into .p12
openssl pkcs12 -export \
-out certificate.p12 \
-inkey private.key \
-in certificate.crt \
-certfile ca.crt
# Extract from .p12
openssl pkcs12 -in certificate.p12 -out extracted.pem -nodes

Test SSL Connections

Test HTTPS Server

# Basic connection test
openssl s_client -connect example.com:443
# With SNI (required for most servers)
openssl s_client -connect example.com:443 -servername example.com
# Test a specific TLS version
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
# Check supported ciphers
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'

Test SMTP with STARTTLS

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

Using Certificates

Nginx

server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.fullchain.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
}

Node.js

const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt'),
ca: fs.readFileSync('ca.crt') // Optional: for client cert verification
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Secure!');
}).listen(443);

Docker Compose

services:
nginx:
image: nginx:alpine
volumes:
- ./certs/server.crt:/etc/nginx/ssl/server.crt:ro
- ./certs/server.key:/etc/nginx/ssl/server.key:ro
environment:
- NODE_TLS_REJECT_UNAUTHORIZED=0 # For development only!

Key Takeaways

  1. SAN is required: Modern browsers need Subject Alternative Names
  2. Local CA for teams: Share one CA, generate multiple certs
  3. Never commit keys: Add *.key to .gitignore
  4. Test connections: Use openssl s_client for debugging
  5. Match key and cert: Verify modulus before deploying
  6. Automate renewal: Track expiration, script regeneration

OpenSSL is the foundation of TLS/SSL management—mastering these commands saves hours of debugging and enables secure development workflows.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive