How to Generate a Self-Signed Certificate with OpenSSL

Updated November 27, 2025 By Server Scheduler Staff
How to Generate a Self-Signed Certificate with OpenSSL

Spinning up a secure, local HTTPS environment is a common task for developers, and the OpenSSL toolkit makes it incredibly straightforward. In development and testing scenarios, you don't need a publicly trusted certificate from a Certificate Authority (CA). Instead, you can generate a self-signed certificate, which provides the same level of encryption for your local servers. This is perfect for enabling HTTPS on localhost or internal staging servers, allowing you to test features that require a secure context without any delays.

Ready to streamline your development workflow? Server Scheduler helps teams manage cloud infrastructure effortlessly with simple, point-and-click automation, reducing manual tasks and cutting costs. Explore how Server Scheduler can simplify your cloud management.

Ready to Slash Your AWS Costs?

Stop paying for idle resources. Server Scheduler automatically turns off your non-production servers when you're not using them.

Understanding Self-Signed Certificates

Before we dive into the commands, it's important to understand why learning to generate a self-signed certificate with OpenSSL is a fundamental skill. Production websites use certificates issued by a trusted Certificate Authority (CA) like Let's Encrypt or DigiCert. These CAs are recognized globally by web browsers, which creates a "chain of trust" and gives users the reassuring padlock icon. However, obtaining a CA-signed certificate for a local domain like localhost is impractical and often impossible. This is where self-signed certificates come in. You essentially act as your own CA, signing the certificate yourself to enable HTTPS for internal use.

A clean workspace featuring a laptop, succulent plant, notebook, and 'DeV Certificates' sign.

Self-signed certificates allow you to create a local development environment that mirrors your production setup. This is crucial for testing modern web features that require a secure context, such as service workers, secure cookies, and certain browser APIs. Without HTTPS, these functionalities may fail silently, leading to unexpected bugs when you deploy your application to production. By using a self-signed certificate, you can debug application behavior in a secure environment early in the development cycle, which is a key part of effective test environment management best practices. The main difference is browser trust; while a self-signed certificate provides valid encryption, your browser will initially display a warning because it doesn't recognize you as a trusted authority. The solution is to manually add the certificate to your local system's trust store.

Callout: Using a self-signed certificate allows you to debug and verify application behavior in a secure context long before deployment, preventing last-minute surprises.

For this task, OpenSSL is the industry-standard tool. It’s free, powerful, and pre-installed on most operating systems, including Linux and macOS. Its command-line interface provides unparalleled flexibility for creating and managing certificates, making it an essential utility for developers and system administrators. Knowing how to use it effectively complements your knowledge of other security tools, such as web application security testing tools.

Creating Your First Self-Signed RSA Certificate

It's time to generate our first certificate. We'll start with a single OpenSSL command that creates both a self-signed certificate and its corresponding RSA private key. This is the quickest method to get an HTTPS server running on localhost or an internal machine. The RSA algorithm is a long-standing and reliable choice for public-key cryptography, making it an excellent starting point. The command we are about to run is interactive and will prompt you to enter information that will be embedded in the certificate, known as the Distinguished Name (DN).

A laptop screen displays OpenSSL software, showing Server.Key, Server.Crt, and "GENERATE RSA CERT" text.

To generate the key and certificate in one step, open your terminal and run the following command. It uses the openssl req utility, which handles certificate signing requests. The -x509 flag is the key component here, telling OpenSSL to create a self-signed certificate instead of a request for a CA to sign. We also specify the key type, output files, and validity period.

openssl req -x509 -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.crt -days 365

After running the command, OpenSSL will ask for details to build the certificate's Distinguished Name. For local development, most of these fields are not critical and can be left blank by pressing Enter. However, the Common Name (CN) is important; it must match the hostname you will use in your browser, such as localhost. While modern browsers prioritize Subject Alternative Names (SANs), setting the CN correctly is still a required step. Once complete, you will have two files: localhost.key (your private key) and localhost.crt (your public certificate). The private key must be kept secret; you can secure its file permissions on Linux or macOS with chmod 600 localhost.key. Protecting keys is as fundamental as having a strategy for backing up Linux systems.

Modernizing with Subject Alternative Names (SANs)

While the Common Name was once the standard for identifying a server, modern browsers have deprecated its use in favor of the Subject Alternative Name (SAN) extension. If a certificate lacks a SAN entry, browsers like Chrome will throw an error, even if the CN is correct. The good news is that SANs are far more flexible, allowing a single certificate to secure multiple hostnames (e.g., localhost, dev.app.local) and IP addresses (e.g., 127.0.0.1). To create a certificate with SANs, we need to use an OpenSSL configuration file instead of a long command-line string.

Using a configuration file, typically with a .cnf extension, is the standard practice for generating modern certificates. This file acts as a template, defining all the necessary values and extensions. Create a file named openssl.cnf and add the following content. This configuration pre-fills the Distinguished Name fields and, most importantly, defines a list of DNS hostnames and IP addresses in the alt_names section. This is crucial when you need to generate a self signed certificate openssl can use for complex applications.

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C = US
ST = California
L = San Francisco
O = My Dev Team
OU = Development
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
DNS.2 = dev.my-app.local
IP.1 = 127.0.0.1
IP.2 = ::1

With the configuration file in place, you can generate the SAN certificate and a new private key with a single command. The -config flag tells OpenSSL to use your custom settings. This command creates a certificate valid for 10 years, which is convenient for long-term development projects.

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout myapp.key -out myapp.crt \
  -days 3650 -config openssl.cnf

Embracing SANs future-proofs your development workflow and eliminates a common source of browser security warnings. It ensures your local environment behaves identically to production, where SANs are a mandatory requirement for all publicly trusted certificates.

A process flowchart illustrating the SAN Certificate creation process: Config, Generate, and Secure steps, represented by modern flat icons against a cool blue background.

Installing and Trusting Your Certificate

You've generated a modern, SAN-equipped certificate, but your work isn't finished. Until your local operating system trusts this certificate, browsers will continue to display security warnings. The final step is to install the public certificate (.crt file) into your system's trust store. This process varies depending on your operating system. For Windows, you use the Microsoft Management Console (MMC) to import the certificate into the "Trusted Root Certification Authorities" store for the "Computer account." For macOS, you use the Keychain Access application, dragging the certificate into the "System" keychain and then explicitly setting its trust level to "Always Trust."

On Debian-based Linux distributions like Ubuntu, the process is handled via the command line. First, copy your certificate to the appropriate directory, ensuring it has a .crt extension.

sudo cp myapp.crt /usr/local/share/ca-certificates/

After copying the file, run the update command to make the system recognize the new certificate.

sudo update-ca-certificates

You should see a confirmation that one new certificate has been added. Once these steps are complete, your browsers and other development tools will trust your certificate, and you will no longer see security warnings for your local domains. Automating tasks like certificate installation can be done with scripting, a topic we cover in our guide on how to run PowerShell scripts.

Configuring Web Servers

With a trusted certificate ready, the final step is to configure your web server to use it. This involves telling the server where to find the certificate and private key files and enabling HTTPS on port 443. For Nginx, you add ssl_ directives to your server block, typically located in /etc/nginx/sites-available/. The ssl_certificate and ssl_certificate_key directives point to your .crt and .key files, respectively. Always validate your changes with nginx -t before restarting the service, a process detailed in our guide on how to check your Nginx configuration.

For Apache, the process is similar. First, ensure the SSL module is enabled with sudo a2enmod ssl. Then, edit your VirtualHost configuration file, usually in /etc/apache2/sites-available/, to listen on port 443. Inside the VirtualHost block, you will set SSLEngine on and specify the paths to your certificate and key files using SSLCertificateFile and SSLCertificateKeyFile. After saving the configuration, restart Apache to apply the changes. Implementing these settings correctly is a core part of a strong secure configuration policy.

Frequently Asked Questions

When you generate a self-signed certificate with OpenSSL, a few common questions often arise, especially when troubleshooting. The most frequent issue is persistent browser warnings even after installing the certificate. This is almost always caused by a mismatch between the hostname in the URL and the Subject Alternative Names (SANs) listed in the certificate. Double-check your .cnf file to ensure every hostname and IP address you use is included, then regenerate the certificate. Another common question is about certificate renewal. Since you are the CA, you don't "renew" a self-signed certificate; you simply generate a new one using the same commands and replace the old files on your server. To avoid this, it's common practice to issue development certificates with a long validity period, such as 10 years (-days 3650).

Finally, developers often ask if self-signed certificates can be used in production. The answer is an emphatic no. They are intended only for internal, non-public environments like local development, staging, and private APIs. Using one on a public website will trigger severe security warnings for all visitors, destroying user trust. The distinction between certificate types and their use cases is fundamental. For more insights into automating infrastructure tasks, explore our article on what DevOps automation is.

Issue Common Cause Solution
Browser Warnings Missing or incorrect Subject Alternative Names (SANs). Verify all hostnames and IPs are in the openssl.cnf file and regenerate the certificate.
Expired Certificate The certificate's validity period has ended. Generate a new certificate with a longer validity period (e.g., -days 3650) and replace the old files.
Server Error Incorrect file paths in the web server configuration. Double-check the paths to the .crt and .key files in your Nginx or Apache config.

  • How to Run PowerShell Scripts for Automation
  • Test Environment Management Best Practices
  • The Ultimate Guide to Backing Up Linux Systems