Console9

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.

Create a self-signed SSL/TLS certificate and private key for local development, testing, and internal services using OpenSSL's req subcommand.

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 -text

How 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:8443

The 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.