How To Create A Self-Signed SSL Certificate With OpenSSL

Profile image of Mattias Geniar

Mattias Geniar, August 06, 2015

Follow me on Twitter as @mattiasgeniar

Creating a self-signed SSL certificate isn't difficult with OpenSSL. These kind of SSL certificates are perfect for testing, development environments or anything else that requires SSL, but that doesn't necessarily have to be a trusted SSL certificate.

If you use this in an Nginx or Apache configuration, your visitors will see a big red "Your connection is not private" warning message first, before they can browse through. This isn't for production, just for testing.

To generate a self-signed SSL certificate in a single openssl command, run the following in your terminal.

$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes

You'll be prompted for several questions, the only that that really matters is the Common Name question, which will be used as the hostname/dns name the self-signed SSL certificate is made for. (Although: even with a valid Common Name, it's still a self-signed SSL certificate and browsers will still find it invalid untrusted.)

Here's the output of that command.

$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes

Generating a 2048 bit RSA private key ………………………..+++ …………..+++ writing new private key to ‘certificate.key’

You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.', the field will be left blank.

Country Name (2 letter code) [AU]:BE State or Province Name (full name) [Some-State]:Antwerp Locality Name (eg, city) []:Antwerp Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Organization Ltd Organizational Unit Name (eg, section) []:IT Department Common Name (e.g. server FQDN or YOUR name) []: your.domain.tld Email Address []:info@yourdomain.tld

If you don't want to fill in those questions every time, you can run a single command with the Common Name as a command line argument. It'll generate the self-signed SSL certificate for you straight away, without pestering you for questions like Country Name, Organization, ...

$ openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes -subj '/CN=my.domain.tld'

Generating a 2048 bit RSA private key …..+++ ………………………+++ writing new private key to ‘certificate.key’

The result with both openssl commands will be 2 new files in your current working directory.

$ ls -alh
-rw-r--r--   1 mattias  1.7K  certificate.crt
-rw-r--r--   1 mattias  1.6K  certificate.key

You can use the certificate.key as the key for your SSL configurations. It doesn't have a password associated with it, that's what the -nodes (No DES encryption) option was for when running the openssl command. If you want a password on your private key, remove that option and run the openssl command again.

$ cat certificate.key

The certificate.crt contains your certificate file, the "public" part of your certificate.

$ cat certificate.crt

Now you have a self-signed SSL certificate and a private key you can use for your server configurations.

Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.