Storing password and confidential data across multiple computer is always a complex problem to solve. They are great tools, such as keypass, that can do this in a secure manner, but for some reason I always felt uneasy about giving my bank password to a 3rd party software.

So, I made my own. It's a simple file encrypted in aes-256-cbc using openssl.

Create a new encrypted file using this command:

echo "my new credential file" | openssl aes-256-cbc -e -a -salt -out mycredentials.encrypted

This creates the file "mycredentials.encrypted". You can then use the scripts below to read your credentials:

getsecret,sh

#!/usr/bin/env bash
if [[ -x "$1" || ! -r "$1" ]]; then
    echo "usage: $0 <ciphered file>"
    exit 1
fi
SECFILE=$1
CLEARTEXT=$(openssl aes-256-cbc -d -a -salt -in $SECFILE)
if [ $? -gt 0 ]; then
    echo "Wrong password, cannot decrypt"
    exit $?
else
    echo "$CLEARTEXT"
fi

storesecret.sh

#!/usr/bin/env bash
# store a password in a ciphered file
if [[ $1 = "" || ! -r $1 ]]; then
    echo "usage: $0 <ciphered file>"
    exit 1
fi
SECFILE=$1

# decipher access file
CLEARTEXT=$(openssl aes-256-cbc -d -a -salt -in $SECFILE)
if [ $? -gt 0 ]; then
    echo "Wrong password, cannot decrypt"
    exit $?
fi

# get new value to store
echo "enter value to append (1 line)"
echo -n "> "
read PASSWD
UPDATED_CLEARTEXT=$(echo -e "$CLEARTEXT\n$PASSWD")

# cipher access file and delete temporary file
echo "$UPDATED_CLEARTEXT"| openssl aes-256-cbc -e -a -salt -out $SECFILE.updated
if [ $? -gt 0 ]
then
    echo "Password encryption failed, password not stored in $SECFILE"
else
    mv "$SECFILE.updated" "$SECFILE"
    echo "information successfully encrypted and store in $SECFILE"
fi
#clean up
CLEARTEXT=$(dd if=/dev/urandom bs=128 count=128 2>/dev/null)
PASSWD=$(dd if=/dev/urandom bs=128 count=128 2>/dev/null)
UPDATED_CLEARTEXT=$(dd if=/dev/urandom bs=128 count=128 2>/dev/null)

There is a couple of drowbacks with this method:

  • Your decrypted credentials are stored in cleartext in a BASH variable at some point, The variables are flushed at the end of the storage process, but you don't want to run this script on an untrusted machine
  • Credentials are displayed in your terminal. Make sure you don't leave that open, and use ./getsecret.sh <credential_file> | grep "bank" to retrieve only the credentials you want, and not the whole file.
  • The storage password requires that you type your password 3 times. That's the only safe way to encrypt/decrypt without passing the password on the command line.

It's definitely not a perfect solution, but I like to do things the hard way :)