3
\$\begingroup\$

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
}
asked Mar 16, 2017 at 16:22
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

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.

answered Mar 16, 2017 at 23:11
\$\endgroup\$
1
  • \$\begingroup\$ Hey, nice - my answer and yours complement each other, and make a complete answer between us. Thumbs up for the team-work! \$\endgroup\$ Commented Mar 17, 2017 at 12:14
3
\$\begingroup\$

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
}
answered Mar 16, 2017 at 18:55
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.