Hybrid symmetric-asymmetric encryption for large files

2013-10-12
#bash

Assymetric encryption is useful if you want to encrypt data at remote server via script. In case you use bash script for symmetric encryption job, you have to store password inside this script. So, if remote server is compromized, you will loose both the encrypted data and the key to decrypt it. Assymetric encryption allows you not to store decryption key at remote machine. So, data will be in safe even if server is hacked.

Assymetric encryption is slow and cannot be applied for large files. The solution is to use hybrid symmetric-assymetric encryption for big data situation. It works as follows: big file is encrypted with symmetric algorythm with on the fly generated key. Key is stored in the file and encrypted with assymetric algorythm.

Bash scripts to encrypt and decrypt files are provided below. To simulate situation with local and remote machines, create local and remote folders side by side. Change directory to local folder, create public and private keys pair and copy public key (keynames are keyfile.key for private and keyfile.pub for public) to remote folder:

cd local
openssl genrsa -out keyfile.key 4096
openssl rsa -in keyfile.key -pubout -out keyfile.pub
cp keyfile.pub ../remote/

Now change directory to remote folder. Create bash script encrypt.sh:

#!/bin/bash

file=$1
passfile=${file}_pwd
pubkey=keyfile.pub

openssl rand 256 > ${passfile}

tar cz $file | openssl enc -aes-256-cbc -salt -out ${file}.enc -pass file:./${passfile}
openssl rsautl -encrypt -pubin -inkey ${pubkey} -in ${passfile} -out ${passfile}.enc

rm ${file} ${passfile}
cp ${file}.enc ${passfile}.enc ../local

Make it executable:

chmod +x ./encrypt.sh

Now you can create testfile with text “secret data” and encrypt it with script encrypt.sh. Resulting encrypted files will be copied to ../local folder.

echo "secret data" > testfile
./encrypt.sh testfile

Now change directory to local folder. Create bash script decrypt.sh:

#!/bin/bash

file=$1
passfile=${file%.enc}_pwd.enc
privatekey=keyfile.key

openssl rsautl -decrypt -inkey ${privatekey} -in ${passfile} -out ${passfile%.enc}
openssl enc -d -aes-256-cbc -in ${file} -pass file:./${passfile%.enc} | tar xz

rm ${file} ${passfile} ${passfile%.enc}

Make it executable:

chmod +x ./decrypt.sh

Now decrypt testfile:

./decrypt.sh testfile.enc

Decypted testfile will be placed into local directory.