Thursday, March 3, 2011

Encrypting with the openssl in bash

With a bit of commandlinefu it becomes easy to encrypt and decrypt files with the strong 256 bit aes algorithm using openssl.

Add the following into your ~/.bashrc
# crypting functions
function encrypt {
  if [ -t 0 ]; then
    # interactive
    local fname="$1"
    shift
    openssl aes-256-cbc -salt -in "$fname" -out "${fname}.enc" $@
  else
    # piped
    perl -e 'use IO::Select; $ready=IO::Select->new(STDIN)->can_read();'
    openssl aes-256-cbc -salt $@
  fi
}
function decrypt {
  if [ -t 0 ]; then
    # interactive
    local fname="$1"
    shift
    openssl aes-256-cbc -d -in "$fname" -out "${fname%\.*}" $@
  else
    perl -e 'use IO::Select; $ready=IO::Select->new(STDIN)->can_read();'
    openssl aes-256-cbc -d $@
  fi
}

and source it to let changes take effect (source ~/.bashrc).



Now call 'encrypt someFilename' enter a password and this file will be encrypted and stored as 'someFilename.enc' in the current directory. Adding the '-a' switch after the file name allows to store an encrypted file in the base64 encoding format which is suitable for piping it into the sendmail for example. To decrypt the file call 'decrypt someFilename.enc'.

If started without parameters, encrypt and decrypt will read from the standard input. One line of code in perl is included to wait until something is written into the command's standard input buffer. This is needed to make it possible to pipe two commands that ask for a password. For example if I would write 'encrypt | decrypt' then it would not work because both commands would ask for a password at the same time! This line of code is preventing the second command from start working until the first one puts something into its standard output. Still this line is added mainly of an academic interest as a solution for a general problem of postponing piped program execution and can safely be removed.

Example of commands usage:
The following command will tar all files in the current directory and encrypt them:
tar -czf - *|encrypt > allfiles.tgz.enc
To decrypt files one can use
decrypt allfiles.tgz.enc
or
cat allfiles.tgz.enc|decrypt|tar -xzf -
to decrypt and extract files on the fly

No comments: