How to generate a self-signed certificate with OpenSSL
Create a self-signed SSL certificate and private key for development and testing using OpenSSL req on Linux and macOS.
- Prerequisites
- Step-by-Step: Generate a Self-Signed Certificate with OpenSSL
- 1. Generate a Private Key and Self-Signed Certificate in One Command
- 2. Generate a Self-Signed Certificate with Subject Alternative Names
- 3. Verify the Generated Certificate with OpenSSL
- How to Verify the Self-Signed Certificate Works
- Common Issues When Generating Self-Signed Certificates with OpenSSL
Create a self-signed SSL/TLS certificate and private key for local development, testing, and internal services using OpenSSL's
reqsubcommand.
Prerequisites
- OpenSSL installed
- Terminal access
- A directory to store the generated certificate and key files
Step-by-Step: Generate a Self-Signed Certificate with OpenSSL
1. Generate a Private Key and Self-Signed Certificate in One Command
OpenSSL's
req subcommand generates a new private key and self-signed certificate simultaneously with the
-x509 flag:
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost"The
-newkey rsa:2048 flag generates a 2048-bit RSA private key. The
-nodes flag creates the key without a passphrase (required for automated server use). The
-days 365 flag sets the certificate validity to one year. The
-subj flag sets the Common Name (CN) without interactive prompts.
2. Generate a Self-Signed Certificate with Subject Alternative Names
Modern browsers require Subject Alternative Names (SANs) and ignore the CN field. Create a certificate with SANs using an OpenSSL configuration extension:
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"The
-addext flag (OpenSSL 1.1.1+) adds the SAN extension inline. For older OpenSSL versions, use a configuration file with the
[alt_names] section.
3. Verify the Generated Certificate with OpenSSL
Inspect the generated certificate to confirm the subject, SANs, and expiration date:
openssl x509 -in server.crt -noout -textHow to Verify the Self-Signed Certificate Works
Test the certificate with
cURLusing the
--cacert flag to trust the self-signed certificate:
curl --cacert server.crt https://localhost:8443The cURL request succeeds without SSL errors when the certificate matches the hostname and the
--cacert flag points to the correct certificate file.
Common Issues When Generating Self-Signed Certificates with OpenSSL
Browser shows "NET::ERR_CERT_COMMON_NAME_INVALID"— The certificate lacks SANs. Modern browsers (Chrome 58+, Firefox 48+) require the
subjectAltName extension and ignore the CN field. Regenerate the certificate with the
-addext "subjectAltName=..." flag.
Nginx or Apache fails to start with "SSL_CTX_use_PrivateKey_file failed"— The private key file does not match the certificate, or the file permissions prevent the web server from reading it. Verify the key matches with
openssl x509 -noout -modulus -in server.crt | md5sum and
openssl rsa -noout -modulus -in server.key | md5sum— the hashes must match.