Home > HowTo's > Simple bash variable security with OpenSSL

Simple bash variable security with OpenSSL

November 17th, 2010 Leave a comment Go to comments

Lets say you have a script that requires a number of variables to operate such as a database connection that requires a server, username and password. It’s usually a good idea to keep all this config in one place but dumping this in a plain text file is usually a bad idea.
The example below allows you to place application level config into a decently encrypted file and keep it all behind one master password.
To do all this we need two files. The first is obviously the encrypted variable config itself. The second is your script file which needs to decrypt the config file and perform whatever action is needed.

In this example I’m going to assume we are connecting to a remote database. Most protocols require three pieces of data to pull this off: a server, a username and a password. We are going to store these three pieces of data in a file called config.plain, encrypt this file (making config.aes), extract its variables and finally connect to our remote database.

I’m going to use the following example config.plain file:

?Download config.plain
SERVER=FooBar
USER=JOE
PASS=RANDOM

So we need to encrypt our config.plain file and turn it into config.aes (AES being the encryption standard we are using). The following example is cheerfully swiped from the example given over at Tombuntu.

>openssl aes-256-cbc -a -salt -in config.plain -out config.aes

So if we wanted to reverse this and decrypt the config.aes file on the command line we could run:

>openssl aes-256-cbc -d -a -salt -in config.aes

NOTE: For some reason the OpenSSL CLI doesn’t obey the Unix standard of specifying ‘-’ as a file name to output to the console. Omitting the ‘-out’ argument will instead output to STDOUT.

Putting it all together

The config.plain example file:

?Download config.plain
SERVER=FooBar
USER=JOE
PASS=RANDOM

The config.aes file (same as above but after encryption using the password ‘password’):

?Download config.aes
U2FsdGVkX19aTdTnSuV1p5R6DCQxp21yrlCc+9j9dap/ziojbiDP1SbSM+6HXF0T
PabsGQgSdV8Ir4rmMjgyFA==

The actual script file which does the decryption and performs the final actions on the data.
We are going to accept the master password from the command line (so we would run the below as ‘script password’ – assuming our script was called ‘script’ and the password was ‘password’). This is not the most secure method available since you can see the launch method of all applications running on the system using ‘ps’. If you want more security I would instead store your password in a system variable and use that instead of reading from the command line. If you wish to do this you can simply strip out all the lines that do error checking and use ‘KEY’ as a system variable to store the master password.

?Download script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash
# USAGE: script <password>
# Do something with the associated config.aes script in a reasonably secure way
#
# Example config.plain content:
# SERVER=FooBar
# USER=JOE
# PASS=RANDOM
#
# Command to encrypt config.plain -> config.aes
# openssl aes-256-cbc -a -salt -in config.plain -out config.aes
 
# Do some housekeeping to check we launched with the requisite number of arguments
if [ "$#" -ne 1 ]; then
	echo "USAGE: $0 <password>"
	exit 1
fi
KEY="$1"
 
# Import the variables from our decrypted stream
STREAM=`openssl aes-256-cbc -d -pass "pass:$KEY" -a -salt -in config.aes`
if [ "$?" -ne 0 ]; then
	echo "Invalid password specified to decrypt configuration file. Aborting."
	exit 1
fi
source <(echo "$STREAM")
 
# REPLACE THE STUFF BELOW THIS LINE WITH WHAT YOU WANT TO DO WITH YOUR SECURE VARIABLES
echo "Server: $SERVER"
echo "Username: $USER"
echo "Password: $PASS"
Categories: HowTo's Tags:
  1. No comments yet.
  1. No trackbacks yet.
*