The Developer Toolbox: Encryption/Decryption with the OpenSSL Command-Line Interface
Every software developer has a toolbox. This toolbox may look a bit different from that of a toolbox used by, let’s say … a carpenter, but the purpose behind the toolbox is about the same: Everything inside the toolbox is there for a reason, to aid the owner in accomplishing their task(s) in the most efficient manner possible.
For example, here are some of the tools you’ll likely find in every developer toolbox (besides a computer, of course):
- A text editor and/or IDE (Integrated Development Environment)
- A preferred Terminal or Shell (Bash, ZSH, TMUX, etc.)
- A version control system (Git, SVN, CVS)
While there are certainly tools that most every developer will have in their toolbox, each developer will likely have a vastly different set of tools from the next developer. The tools in the toolbox will be largely dependent upon the area of work/focus for that specific developer. Much like our earlier comparison to a carpenter, most carpenters will have some of the same tools (hammer, screwdriver, tape measure, etc.) and have vastly different tools based on their specialization (e.g. not every carpenter is going to have a socket awl in their toolbox).
Over the past couple of weeks, I have been working on a project that implements strong encryption of data that is shared between different backend services we run and maintain in support of our desktop client software. As a part of this project, I needed a tool to be able to quickly test encryption and decryption of data without using only the code I was writing. This type of testing would allow me to make sure that my encryption/decryption methods were correct and reliable. So, what kind of tool would allow me to do this?
The OpenSSL Command-Line Interface
One of the backend services I was working on is written in C/C++ and utilizes the OpenSSL library for both SSL/TLS as well as other cryptographic functions. If you’re unfamiliar with OpenSSL, it’s likely one of most widely implemented open-source libraries out there today, so there is a wealth of documentation and other information freely available.
In addition to being a library that can be used in our programs, OpenSSL can also be downloaded and installed as a command-line interface. If you’re a Mac or Linux user, this is already installed on your computer! (Note: after High Sierra/MacOS 10.13 was released, Apple no longer uses the OpenSSL library, but has switched to LibreSSL. Despite the change, much of the functionality should be identical to that in OpenSSL, and where this post is concerned, the functionality will definitely be the same.) If you are running Windows, you will need to download and install OpenSSL, you can find download links here.
The specific functionality I was interested in was to be able to encrypt and decrypt a string using the same cipher I would be using in the applications I was working on. Turns out the OpenSSL command-line interface (CLI), specifically the
enc command, would be the perfect tool to help me test my implementations! Let’s take a look at a few examples and how this tool works and how it made me more efficient in my work.
Let’s walk through a few different commands. If you want to follow along, just open a terminal!
Encrypt a string
Let’s say we wanted to encrypt the string “hello” with the passphrase “world” using the AES-256 algorithm in CBC (Cipher Block Chaining) mode.
$ echo "hello" | openssl enc -aes-256-cbc -base64 -p -k world
Let’s break down this command before we look at the output:
echo hello- alone, this would just print the word
hellointo the terminal, but combined with the pipe operator
hellowill now be “piped into” our
opensslcommand for transformation.
openssl enc -aes-256-cbc- so, next we have a couple of things worth mentioning. First,
opensslis just the name of the “program” we’re executing. Next
enc -aes-256-cbcis asking the openssl program to use the
enccommand (encryption) and the
-aes-256-cbcis telling the program to use the AES-256-CBC cipher to encrypt the data we’ve piped into the program.
- Lastly we have some additional options we’ve passed to the
-base64- this tells openssl to print the encrypted output as a base64 encoded string. This makes it much easier to copy/paste the encrypted output using readable characters.
-ptells openssl to print the Salt, Key, and IV as a string of hex digits. This is very useful when needing to reuse the same Key and IV during decryption.
-k world- This is the passphrase we’re using to encrypt the string we piped into openssl. This could have been left out and openssl would have prompted you for a password.
So, let’s see what we get when we run this command:
salt=28E81662F21E8F44 key=7727DBCC7C11E479564F13C93E28BA8AEABFD3CFF1F81C78858869050D75F5CA iv =69E71D3EFF53EF6B4B751622CD272A62 U2FsdGVkX18o6BZi8h6PRJ7AUNyeMDHnhLEl06AS3KA=
The last line here is the really important one. This is the base64 encoded output of the encryption method. This is what we’re now going to attempt to decrypt.
Decrypt a string
So, we know that the encrypted message is just the word “hello,” but for the sake of the article, let’s pretend we don’t know that. Given we knew the passphrase used to encrypt the original data, how could we go about decrypting the string
U2FsdGVkX18o6BZi8h6PRJ7AUNyeMDHnhLEl06AS3KA=? Let’s find out!
$ echo "U2FsdGVkX18o6BZi8h6PRJ7AUNyeMDHnhLEl06AS3KA=" | openssl \ enc -aes-256-cbc -d -a -p -k world
So, what’s going on here?
echo "U2FsdGVkX18o6BZi8h6PRJ7AUNyeMDHnhLEl06AS3KA=" | openssl- Much like our encryption example, we’re just piping our base64 encoded string to openssl for transformation
enc -aes-256-cbc -d- This is identical to the encryption example save for the
-doption. This is telling openssl that we want to decrypt an input to the program.
- Now for the additional options we’re passing in:
-a- this is equivalent of using
-base64. When used in combination with
-dopenssl will first base64 decode the input and then decrypt it.
-p -k world- This is the same as our encryption example,
-pis printing the various inputs to the decryption algorithm and
-k worldis specifying the passphrase to use for decryption.
Well … let’s run it and see what we get:
salt=28E81662F21E8F44 key=7727DBCC7C11E479564F13C93E28BA8AEABFD3CFF1F81C78858869050D75F5CA iv =69E71D3EFF53EF6B4B751622CD272A62 hello
AWESOME!! This is exactly what we wanted to see! We see that our encrypted message is
hello and that our salt, key, and IV all match!
So, to conclude, I’ve used a fairly trivial example to demonstrate how the OpenSSL CLI can be used to encrypt and decrypt data. There is much more this tool can do and many different ways in which it can be helpful. For full documentation of the
openssl enc command, please see this page. You can further use the tool to use different ciphers, you can encrypt and decrypt complete files, you can specify the digest algorithm used to generate the key from the passphrase you provide (default is SHA-256), and much more.