2019-03-13 01:39:49 +01:00
|
|
|
import hashlib
|
2019-03-12 22:41:07 +01:00
|
|
|
import sys
|
|
|
|
|
2019-03-14 11:50:17 +01:00
|
|
|
try:
|
|
|
|
import requests
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
print("### pip install requests ###")
|
|
|
|
raise
|
|
|
|
|
2019-03-12 22:41:07 +01:00
|
|
|
|
|
|
|
def lookup_pwned_api(pwd):
|
2019-03-13 01:41:42 +01:00
|
|
|
"""Returns hash and number of times password was seen in pwned database.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
pwd: password to check
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
A (sha1, count) tuple where sha1 is SHA1 hash of pwd and count is number
|
|
|
|
of times the password was seen in the pwned database. count equal zero
|
|
|
|
indicates that password has not been found.
|
2019-03-12 22:41:07 +01:00
|
|
|
|
2019-03-13 01:41:42 +01:00
|
|
|
Raises:
|
|
|
|
RuntimeError: if there was an error trying to fetch data from pwned
|
|
|
|
database.
|
2019-03-14 15:33:15 +01:00
|
|
|
UnicodeError: if there was an error UTF_encoding the password.
|
2019-03-13 01:41:42 +01:00
|
|
|
"""
|
2019-03-14 11:50:17 +01:00
|
|
|
sha1pwd = hashlib.sha1(pwd.encode('utf-8')).hexdigest().upper()
|
2019-03-13 01:41:42 +01:00
|
|
|
head, tail = sha1pwd[:5], sha1pwd[5:]
|
2019-03-13 02:23:20 +01:00
|
|
|
url = 'https://api.pwnedpasswords.com/range/' + head
|
|
|
|
res = requests.get(url)
|
|
|
|
if res.status_code != 200:
|
|
|
|
raise RuntimeError('Error fetching "{}": {}'.format(
|
|
|
|
url, res.status_code))
|
2019-03-13 01:41:42 +01:00
|
|
|
hashes = (line.split(':') for line in res.text.splitlines())
|
|
|
|
count = next((int(count) for t, count in hashes if t == tail), 0)
|
|
|
|
return sha1pwd, count
|
2019-03-12 22:41:07 +01:00
|
|
|
|
|
|
|
|
2019-03-13 02:26:20 +01:00
|
|
|
def main(args):
|
2019-03-13 02:32:18 +01:00
|
|
|
ec = 0
|
2019-03-13 02:31:23 +01:00
|
|
|
for pwd in args or sys.stdin:
|
|
|
|
pwd = pwd.strip()
|
2019-03-14 15:33:15 +01:00
|
|
|
try:
|
|
|
|
sha1pwd, count = lookup_pwned_api(pwd)
|
|
|
|
|
|
|
|
if count:
|
|
|
|
foundmsg = "{0} was found with {1} occurrences (hash: {2})"
|
|
|
|
print(foundmsg.format(pwd, count, sha1pwd))
|
|
|
|
ec = 1
|
|
|
|
else:
|
|
|
|
print("{} was not found".format(pwd))
|
|
|
|
except UnicodeError:
|
|
|
|
errormsg = sys.exc_info()[1]
|
|
|
|
print("{0} could not be checked: {1}".format(pwd, errormsg))
|
2019-03-13 02:32:18 +01:00
|
|
|
ec = 1
|
2019-03-14 15:33:15 +01:00
|
|
|
continue
|
2019-03-13 02:32:18 +01:00
|
|
|
return ec
|
2019-03-13 02:26:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2019-03-13 02:32:18 +01:00
|
|
|
sys.exit(main(sys.argv[1:]))
|