Password Checker
Have you ever wondered if your password has been breached or exposed to the internet before? If you use the same password for multiple websites, that’s unfortunate because it may have been exposed to the public. To testify this, we can use haveibeenpwned api to (not really) give our password and check against public data.
First off, we have to hash our password using sha-1. In linux, you can use command sha1sum to transform text into sha-1 hash. Hash is a one way operation meaning that you can only transform the input to the output deterministically and not vice versa.
PASSWORD="$(echo -n "$RAW" | sha1sum | awk '{print $1}' | tr '[:lower:]' '[:upper:]')"
PREFIX="${PASSWORD:0:5}"
After that we need to extract first 5 characters from the hashed password and
append it to this url https://api.pwnedpasswords.com/range/$PREFIX
where
$PREFIX
is the variable which holds the first 5 character of our hashed
password.
To make a request against the api, you can use
curl. Option -Ss
is used to silent the
verbose output and only show error message if it fails.
RANGE_PASSW=$(curl -Ss "https://api.pwnedpasswords.com/range/$PREFIX")
The output of the curl command will look like this:
F971582870552CF5BA8DD23C8EC01F99A0A:2
F984473B8ED4FBC1C83E03146668A2CEBEC:2
F9F50FE2D40187D3681AA1BDD6733C8914E:2
FA4D46A28BB6C52C0260CE565C771D4A8E0:2
FAFFD17C2F38B0A9DBF5E112DC3A005C06C:5
FB064758EB0BC12238ACC06280DA6D46259:1
... more
The output is a list of hash strings that matches the first 5 character of our hashed password. This is due to the security measurement taken by haveibeenpwned so that they don’t know the exact password hash you tried to check against their API.
Now, the output has the following format {password hash without prefix:instances of password have been pwned}
. We can use bash string substring
built-in to extract the information we need from the curl output.
PW=${RES%:*} # capture everything before ':'
COUNT=${RES#*:} # capture everything after ':'
Now all is left is to find which password belongs to ours. We can simply loop through the list and check against our hashed password without the first 5 character suffix.
while read -r RES; do
PW=${RES%:*}
COUNT=${RES#*:}
if [[ $SUFFIX = $PW ]]; then
printf "password has been found %d times(s)\n" "$COUNT" 2>/dev/null
exit
fi
done <<< "$RANGE_PASSW"
echo "password has been found 0 time(s)"
The complete script is given below:
#!/usr/bin/env bash
read RAW
PASSWORD="$(echo -n "$RAW" | sha1sum | awk '{print $1}' | tr '[:lower:]' '[:upper:]')"
PREFIX="${PASSWORD:0:5}"
SUFFIX="${PASSWORD:5}"
RANGE_PASSW=$(curl -Ss "https://api.pwnedpasswords.com/range/$PREFIX")
while read -r RES; do
PW=${RES%:*}
COUNT=${RES#*:}
if [[ $SUFFIX = $PW ]]; then
printf "password has been found %d times(s)\n" "$COUNT" 2>/dev/null
exit
fi
done <<< "$RANGE_PASSW"
echo "password has been found 0 time(s)"
To use the script, you can either pipe your password into the script or type the password after running it.