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 ...
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.
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.
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