To generate a self-signed SSL certificate using OpenSSL, follow these steps:
1. Basic Command (One-Liner)
This generates a private key (key.pem
) and a self-signed certificate (cert.pem
) valid for 365 days:
openssl req -x509 \
-newkey rsa:2048 \
-keyout key.pem \
-out cert.pem \
-days 365 \
-nodes \
-subj "/CN=localhost" # Replace "localhost" with your domain
Flags Explained:
-x509
: Generates a self-signed certificate (instead of a CSR).-newkey rsa:2048
: Creates a 2048-bit RSA private key.-keyout key.pem
: Saves the private key tokey.pem
.-out cert.pem
: Saves the certificate tocert.pem
.-days 365
: Sets the certificate’s validity period.-nodes
: Disables passphrase protection for the key (optional but convenient for testing).-subj "/CN=..."
: Pre-fills subject info (optional; omit to answer prompts interactively).
2. Generate with Prompts (Interactive)
If you omit -subj
, OpenSSL will prompt for certificate details:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
You’ll be asked for:
- Country Name (2-letter code)
- State/Province Name
- Locality Name
- Organization Name
- Common Name (CN): The domain (e.g.,
localhost
,example.com
).
3. Generate with Subject Alternative Names (SANs)
Modern browsers require SANs for self-signed certificates. Use a config file:
Create openssl.cnf
:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Organization
CN = localhost # Replace with your domain
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost # Add your domain here
IP.1 = 127.0.0.1 # Optional: Add IP addresses
Run:
openssl req -x509 \
-newkey rsa:2048 \
-keyout key.pem \
-out cert.pem \
-days 365 \
-nodes \
-config openssl.cnf \
-extensions v3_req
4. Verify the Certificate
Check the generated certificate’s details:
openssl x509 -in cert.pem -text -noout
5. Use in a Web Server
Example for Node.js:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options, (req, res) => {
res.end('Hello from HTTPS!\n');
}).listen(443);
Notes
- Validity: Replace
365
with your desired validity period (in days). - Trust: Browsers will warn about self-signed certificates. Override manually for testing.
- Production: Use certificates from a trusted Certificate Authority (CA) like Let’s Encrypt.