A while ago I wanted to create my own password manager, something very simple that would enable me to generate random passwords instead of using the same one all over the internet. I ended up using the code below for a few years now.
The idea that I went with was to make two bash scripts:
savepass.sh
used to generate a random password, save it in an encrypted file and keep that file in a git repo, with a private remote GitHub repo (Bitbucket actually, before GitHub allowed unlimited private repos)getpass.sh
used to retrieve the password from the encrypted file and pipe it topbcopy
. (I use Mac OS, but there are Linux alternatives topbcopy
)
It’s not a particularly original idea and you can probably find more robust implementations somewhere on GitHub.
The first step is to generate a gpg key. Here’s a nice tutorial on gpg that should be enough to understand what’s going on here.
Once we’ve generated our key, we can access it from the gpg keychain, and it’s not a bad idea to export the private key and create a backup somewhere, since you can’t recover your passwords without it.
To list the available keys use gpg --list-secret-keys
, that gives you something like this:
------------------------
sec 2048R/ABCD10BF 2019-07-09
uid sh_pass_manager (key for sh_pass_manager) <sh_pass_manager@sh_pass_manager>
ssb 2048R/BAC4160B 2019-07-09
Now we can create the savepass.sh
that will take the service name (eg. “gmail.com”) as a parameter and save the encrypted random password in a file
#!/bin/sh SERVICE_NAME=$1 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" mkdir -p "$SCRIPT_DIR/pass" GPG_RECEPIENT="sh_pass_manager (key for sh_pass_manager) <sh_pass_manager@sh_pass_manager>" openssl rand -base64 32 | gpg --encrypt --recipient "$GPG_RECEPIENT" > "$SCRIPT_DIR/pass/$SERVICE_NAME"
Run this with ./savepass.sh gmail.com
and you should get a file pass/gmail.com
. Open it with less
to check that it’s a garbled binary file.
Note that we used openssl rand -base64 32
to generate a random password which is nothing but 32 random bytes encoded in base64
(see the docs).
We can now write the getpass.sh
to retrieve our encrypted passwords.
#!/bin/sh set -e set -o pipefail PASS_FILE=$1 SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" gpg --decrypt $PASS_FILE | pbcopy echo "Password copied to clipboard
It’s as simple as calling gpg --decrypt
on an encrypted file.
Now, if all this is done inside a git repo, you can backup your encrypted passwords by pushing them to a git remote. (You can also do it automatically upon password creation, at the end of savepass.sh
)
You can clone the two files from https://github.com/drazenz/sh-pass-manager.
Disclaimer: I am by no means a computer security expert, and the simple hack above likely has some security flaws. It’s aimed more as an illustration of a simple unix command line workflow, rather than a properly secured password manager.