Skip to content

Instantly share code, notes, and snippets.

@divVerent
Last active January 8, 2019 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save divVerent/e5301731864f61af9cccb3e772d235a9 to your computer and use it in GitHub Desktop.
Save divVerent/e5301731864f61af9cccb3e772d235a9 to your computer and use it in GitHub Desktop.
Shell port of https://paulgreg.me/UniquePasswordBuilder/ for verification.
#!/bin/sh
# Shell port of https://paulgreg.me/UniquePasswordBuilder/ for verification.
# Same string as UPB; can be changed if OK to break existing passwords.
# See https://github.com/paulgreg/UniquePasswordBuilder/issues/16.
ARGON2_PEPPER='5yB8xbz*BsiMxI8yaz&_9!1u3=ZS$fEH16URassf2OzcZEuvIgt4So0sB2aMAp!SDc#HoHuPZ1_??|X-yw2&J+d+c?AKo-k!ifhH6Qp%25alTVdzE*UAFo9#WduBLCXXZhEjg9V&j#DJQba^e#^NNP'
passwordLength=16
availableChars='!$+-=_.:;,?#%&()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
availableCharsLength=$(printf '%s' "$availableChars" | wc -c)
makeHashHumanReadable() {
while v=$(dd bs=1 count=4 2>/dev/null); [ -n "$v" ]; do
v=0x$v
v=$(((v / 256 + v % 256) % availableCharsLength)) # 6.32 bits.
echo -n "$availableChars" |\
dd bs=1 count=1 skip="$v" 2>/dev/null
done
printf '\n'
}
makeHashHumanReadableFixed() {
# Fixed https://github.com/paulgreg/UniquePasswordBuilder/issues/17.
while v=$(dd bs=1 count=4 2>/dev/null); [ -n "$v" ]; do
v=0x$v
v=$((v % availableCharsLength)) # 6.32 bits, even distribution.
echo -n "$availableChars" |\
dd bs=1 count=1 skip="$v" 2>/dev/null
done
printf '\n'
}
locationSalt=$1
userSalt=$2
scrypt() {
# There's no commandline utility for scrypt, so we have to use Python.
env "$@" python3 -c '
import scrypt
import sys
import os
password = sys.stdin.read().rstrip("\n")
print(scrypt.hash(password,
salt=os.environ["salt"],
N=int(os.environ["N"]),
r=int(os.environ["r"]),
p=int(os.environ["p"]),
buflen=int(os.environ["length"])).hex())
'
}
hashLength=$((2 * passwordLength))
case "${algorithm:-scrypt}" in
scrypt)
if [ -n "$userSalt" ] && [ x"$userSalt" != x'0' ]; then
userSalt="-keyidx:$userSalt"
fi
salt="$locationSalt$userSalt"
echo -n "Password: " >&2
stty -echo
trap 'stty echo' EXIT
head -n 1 |\
scrypt \
salt="$salt" \
N="${difficulty:-8192}" r=8 p=1 \
length="$hashLength" |\
makeHashHumanReadable
;;
argon2)
salt="$locationSalt|${userSalt:-0}|$ARGON2_PEPPER"
echo -n "Password: " >&2
stty -echo
trap 'stty echo' EXIT
head -n 1 |\
argon2 "$salt" -i -r \
-t "${difficulty:-10}" \
-m 10 \
-l "$hashLength" |\
argon2 "$salt" -d -r \
-t "${difficulty:-10}" \
-m 10 \
-l "$hashLength" |\
makeHashHumanReadable
;;
argon2id)
# Fixed https://github.com/paulgreg/UniquePasswordBuilder/issues/21.
salt="$locationSalt|${userSalt:-0}|$ARGON2_PEPPER"
echo -n "Password: " >&2
stty -echo
trap 'stty echo' EXIT
# Fixed https://github.com/paulgreg/UniquePasswordBuilder/issues/22.
set -- $difficulty
cpuDifficulty=${1:-3}
memoryDifficulty=${2:-12}
head -n 1 |\
argon2 "$salt" -id -r \
-t "$cpuDifficulty" \
-m "$memoryDifficulty" \
-l "$hashLength" |\
makeHashHumanReadableFixed
;;
*)
echo "Unsupported algorithm $algorithm." >&2
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment