#!/bin/bash pfile=$1 cPwned=0 cPswds=0 ## Check if the argument is a file we can read if [ ! -f "$pfile" ] then echo "$pfile can not be read." echo exit 2 fi ## Check if the list in the argument is an actual ascii file ## and not something crazy like a zip, etc. filetype=$(file "$pfile") if [ "$filetype" != "$pfile: ASCII text" ] then echo "$pfile is not an ascii password list." echo exit 2 fi ## loop through the file and verify against the api echo "Checking passwords from list $1" IFS=$'\n' for p in $(grep --invert-match '^ #' $pfile); do ((cPswds++)) ## Hash the password, filter non-hashy things (" -" at the end), ## translate to upper for the beauty pHashed=$(echo -n "$p" | sha1sum | cut --delimiter=' ' --fields=1 | tr '[:lower:]' '[:upper:]') ## Devide into prefix and suffix used by k-anonymity model ## https://haveibeenpwned.com/API/v2#PwnedPasswords pPrefix=$(echo -n "$pHashed" | cut --characters='-5') pSuffix=$(echo -n "$pHashed" | cut --characters='6-') ## get a list of pwnedsuffix:pwncount from the webservice wsResult=$(curl --silent https://api.pwnedpasswords.com/range/$pPrefix) ## Check if our suffix is included and strip characters we can not understand wsCheck=$(echo -n "$wsResult" | grep $pSuffix | tr -cd [:alnum:][:]) if [ -n "$wsCheck" ] then ## CheckedResult contains a value --> EVIL pwnCount=$(echo -n "$wsCheck" | cut --delimiter=':' --fields=2) echo "XX: Password $p has been pwned $pwnCount times." ((cPwned++)) else ## CheckedResult does not contain a value --> good echo "__: Password $p has not been pwned." fi done echo "==: $cPwned of $cPswds passwords have been pwned." echo if [ $cPwned -gt 0 ] then exit 1 fi