Kruptos is a simple tool that encrypts and decrypts the ~/.kruptos
directory with the password that is stored in ~/.kruptos/.phrazein
. There are 3 commands:
- e - Encrypt
- d - Decrypt
- i - Initialize
Goal
I have a couple main goals:
- Design: How could I make this more resilient to change?
- Readability: How could I make this more readable?
- Best Practices: Are there aspects of a bash command that I am missing?
# Minimalist password manager
function kruptos
{
# Decipher the flag
if [[ $# -eq 1 ]]; then
DOWHAT="1ドル"
else
DOWHAT="d"
fi
# Perform an action
if [[ $DOWHAT == "d" ]]; then
#Decrypt
pushd . &>/dev/null
cd ~/
openssl aes-256-cbc -d -in .kruptos.tar.gz.aes | tar -xz -f - --strip-components=2 && rm ~/.kruptos.tar.gz.aes
popd &>/dev/null
elif [[ $DOWHAT == "e" ]]; then
#Encrypt
tar -zcf - ~/.kruptos | openssl aes-256-cbc -out ~/.kruptos.tar.gz.aes -kfile ~/.kruptos/.phrazein && rm -r ~/.kruptos
elif [[ $DOWHAT == "i" ]]; then
#Initialize
mkdir ~/.kruptos
echo pswd > ~/.kruptos/.phrazein
else
echo "$DOWHAT is not an acceptable flag"
fi
}
2 Answers 2
I have nothing on the scripting as such, it looks good to me. But given the subject matter, there's one big point, and two small ones:
You're saving the decrypted data on the disk, and removing it just with a plain
rm
. That is likely to leave the decrypted data on the disk in plaintext. For a password encryptor, I think this is quite an issue, even though changing it would require a bit of restructuring. Possibly decrypt the file to a RAM-based filesystem (OS dependant), or add functionality to modify individual entries in-line.Initialization should perhaps ask for the password to be entered instead of setting a fixed one. (Possibly asking twice to make sure the user types it correctly.)
My manual for
openssl
says-kfile $filename
is superseded by-pass file:$filename
In any case, points for using openssl
instead of hand-rolled encryption.
-
\$\begingroup\$ Hey, nice - my answer and yours complement each other, and make a complete answer between us. Thumbs up for the team-work! \$\endgroup\$Toby Speight– Toby Speight2017年03月17日 12:14:51 +00:00Commented Mar 17, 2017 at 12:14
I'll not address the security analysis; I'll assume you've done threat modelling and are happy with the overall approach.
Instead of a chain of if
/elif
all testing the same variable, the natural approach is a switch. I'll also take advantage of ${:-}
to default the argument:
case "${1:-d}" in
d)
# Decrypt
# (commands)
;;
e)
# Encrypt
# (commands)
;;
i)
# Initialize
# (commands)
;;
*)
# invalid
exec >&2
echo "Usage: 0ドル [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
exit 1
;;
esac
Note that I've sent the error message to error output (&2
) and exited with an error code. Actually, this should really be return 1
since it's a function rather than a complete script.
In the decrypt code, you use pushd
and popd
. These are suited to interactive use, but are best left alone in scripts or functions (that's why you discovered that you need to redirect their output). Instead, you can use a sub-shell:
(cd ~; commands... )
or use full paths. In this case, we want tar
to output to ~
, and we can tell it to do so, using its -C
option:
openssl -in ~/.kruptos.tar.gz.aes | tar -C ~ -xz -f -
Finally, you can avoid duplication by putting paths that are used more than once into variables. This protects you against mis-typing any of them, and makes it easier if you should ever want to change them.
Modified code
Here's what I have, after applying the above changes:
function kruptos
{
local dir=~/.kruptos
local file=~/.kruptos.tar.gz.aes
local keyfile="$dir/.phrazein"
case "${1:-d}" in
d)
# Decrypt
openssl aes-256-cbc -d -in \
| tar -C "$dir" xfz - \
&& rm "$file"
;;
e)
# Encrypt
tar -C "$dir" cfz - . \
| openssl aes-256-cbc -out "$file" -kfile "$keyfile" \
&& rm -r "$dir"
;;
i)
# Initialize
mkdir "$dir"
echo pswd >"$keyfile"
;;
*)
# invalid
exec >&2
echo "Usage: 0ドル [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
return 1
;;
esac
}