Encrypting files with OpenSSL
OpenSSL is a great toolkit for working with TLS/SSL protocols, however it can also be used for several other cryptography related tasks. This post is going to quickly go over using OpenSSL to encrypt and decrypt files with a symmetric key.
Selecting an algorithm
The available cipher algorithms will depend on the exact version of OpenSSL
you're using and compile time options, the list-cipher-algorithms
command can
be used to list available ciphers:
$ openssl list-cipher-algorithms
AES-128-CBC
AES-128-CBC-HMAC-SHA1
AES-128-CFB
AES-128-CFB1
AES-128-CFB8
AES-128-CTR
AES-128-ECB
AES-128-OFB
...
Unfortunately the enc
command requires a slightly different format. Details
of the available ciphers can be found in the
enc(1) man page. Alternatively you can run
enc
with and unsupported option (for example openssl enc -help
) to print a
list of cipher options:
$ openssl enc -help
unknown option '-help'
options are
-in <file> input file
-out <file> output file
-pass <arg> pass phrase source
-e encrypt
-d decrypt
-a/-base64 base64 encode/decode, depending on encryption flag
-k passphrase is the next argument
-kfile passphrase is the first line of the file argument
-md the next argument is the md to use to create a key
from a passphrase. See openssl dgst -h for list.
-S salt in hex is the next argument
-K/-iv key/iv in hex is the next argument
-[pP] print the iv/key (then exit if -P)
-bufsize <n> buffer size
-nopad disable standard block padding
-engine e use engine e, possibly a hardware device.
Cipher Types
-aes-128-cbc -aes-128-cbc-hmac-sha1 -aes-128-cfb
-aes-128-cfb1 -aes-128-cfb8 -aes-128-ctr
-aes-128-ecb -aes-128-gcm -aes-128-ofb
...
For the rest of this post I'm going to use a AES with a 128 bit key
and Cipher Block Chaining (aes-128-cbc
), however the process of
encrypting and decrypting files using the enc
command should be very similar
for other algorithms.
Encrypting files
A simple test file can be created with the following command:
$ echo hello world > plain-text.txt
The file can then be encrypted with a command similar to the following:
$ openssl enc -e -aes-128-cbc -in plain-text.txt -out cipher-text.txt
enter aes-128-cbc encryption password:
Verifying - enter aes-128-cbc encryption password:
It's important that the password used to encrypt the file is suitably complex to avoid brute force attacks. The resulting cipher text file will look something like the following:
$ xxd cipher-text.txt
0000000: 5361 6c74 6564 5f5f 5537 e53f 5beb 8d3f Salted__U7.?[..?
0000010: 87ed 1b2d 7f8a 002d 76d7 84c4 26d6 fd74 ...-...-v...&..t
Note: by default a salt will be used with the password to generate the
encryption key. The cipher text file will have a Salted__
signature to
indicate this, followed by an eight byte salt.
Decrypting files
To decrypt the cipher text the -d
option can be used:
$ openssl enc -d -aes-128-cbc -in cipher-text.txt -out decrypted.txt
enter aes-128-cbc decryption password:
$ cat decrypted.txt
hello world
It's worth noting that invalid passwords will be detected, and a non-zero error code is returned:
$ openssl enc -d -aes-128-cbc -in cipher-text.txt -out decrypted.txt
enter aes-128-cbc decryption password:
bad decrypt
139871004383136:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:604:
$ echo $?
1