Cogs and Levers A blog full of technical stuff

Working with OpenSSL

OpenSSL is the open source project that provides the world with SSL and TLS. In today’s post, I’ll walk through some simple tasks to encrypt and decrypt your data.

Features

OpenSSL is a very feature-rich library. It contains many pieces of functionality that you should study in more detail. The man page for it goes into all of these details in great depth.

Encoding information

Perhaps a slightly edge-case piece of functionality, OpenSSL has the ability to Base64 encode your information. It’s no where near actually securing your information, but the facility is there.

You can Base64 encode a string with the following command:

$ echo "Hello, world!" | openssl enc -base64
SGVsbG8sIHdvcmxkIQo=

You can bring it back to plain text with the following:

 
$ echo "SGVsbG8sIHdvcmxkIQo=" | openssl enc -base64 -d
Hello, world!

Encrypt with a password

OpenSSL gives you the ability to encrypt a piece of information using a password. This is a simple way of securing your information without certificates, but isn’t a very strong strategy for information security.

Take a look under the Encoding and Cipher Commands for a full range of strategies here. Where we used the base64 options above, no password was asked for. This is because it’s just an encoding. If we were to use the bf option (which will use the Blowfish Cipher), we’re prompted for a password.

$ echo "Hello, world" | openssl enc -bf > password_enc.dat
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:

password_enc.dat contains what would appear to be garbage, but it is our string; just encrypted. To get our plain text back:

$ openssl enc -bf -d -in password_enc.dat 
enter bf-cbc decryption password:
Hello, world!

You need to enter the correct password in order to get your plain text back. Pretty simple. This is the process for any of the ciphers mentioned above.

Encrypt with a key pair

Stepping up the complexity, you can get OpenSSL to encrypt and decrypt your data using public-key cryptographyy.

First of all, we need to generate a public/private key pair. The following command will generate a private key. This will be an RSA keypair with a 4096 bit private key.

$ openssl genrsa -out private_key.pem 4096
Generating RSA private key, 4096 bit long modulus
....++
......................................................................................................................................................................................................................++
e is 65537 (0x10001)

Now that the private key has been generated, we extract the public key from it:

$ openssl rsa -pubout -in private_key.pem -out public_key.pem
writing RSA key

You can view all of the details of your keypair details with the following command. It’s a pretty verbose information dump, so brace yourself.

$ openssl rsa -text -in private_key.pem

We encrypt the source information with the public key and perform the decryption using the private key.

To encrypt the information:

$ echo "Hello, world" > encrypt.txt
$ openssl rsautl -encrypt -inkey public_key.pem -pubin -in encrypt.txt -out encrypt.dat

To decrypt the information:

$ openssl rsautl -decrypt -inkey private_key.pem -in encrypt.dat -out decrypt.txt
$ cat decrypt.txt 
Hello, world

Working with certificates

You can use OpenSSL to generate a self-signed certificate.

Generating a self-signed certificate is a fairly simple process. The following will generate a certificate and private key (in the one file) that’s valid for 1 year. This certificate’s key won’t be protected by a passphrase.

$ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

You can shorted the key generation process (make it ask less questions) by specifying all of the subject details in the generation command:

$ openssl req -x509 -nodes -days 365 -subj '/C=AU/ST=Queensland/L=Brisbane/CN=localhost' -newkey rsa:4096 -keyout mycert2.pem -out mycert2.pem

Other functions

You can use OpenSSL to generate some random data for you as well. This is useful in scenarios where your application requires nonce data. The rand switch does this easily:

$ openssl rand -base64 128
tfINhtHHe5LCek2mV0z6OlCcyGUaHD6xM0jQYAXPNVpy0tjoEB4gy7m6f/0Fb4/K
cKyDfZEmpvoc3aYdQuCnH1kfJk1EQR1Gbb3xyW22KOcfjuEot5I+feinilJcDfWY
aJKDyuNUOn9YuZ8aALhP1zhA0knAT5+tKtNxjjNar04=

Piping the contents of /dev/urandom through OpenSSL’s base64 encoder will also perform the same task (with better entropy).

Prime testing is an important cryptographic step and can be achieved with the prime switch:

$ openssl prime 3
3 is prime
$ openssl prime 4
4 is not prime
$ openssl prime 5
5 is prime
$ openssl prime 6
6 is not prime

A really practical utility bundled inside of OpenSSL is the testing server that you can instantiate to test out your certificates that you generate.

$ openssl s_server -cert mycert.pem -www

This starts a HTTPS server on your machine. You can point your web browser to https://server:4433/ to see how a browser responds to your certificate.

You can also use OpenSSL as a client to pull down remote certificates:

$ openssl s_client -connect server:443