Last active
December 14, 2020 09:17
-
-
Save giannitedesco/da3752b059f0fe1b4d80a8c4465b64fd to your computer and use it in GitHub Desktop.
Tool to check haveibeenpwnd password database
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
__author__ = 'Gianni Tedesco' | |
__url__ = 'https://github.com/giannitedesco/' | |
__license__ = 'Public Domain' | |
from hashlib import sha1 | |
from getpass import getpass | |
import httpx | |
_prompt = 'hibp> ' | |
def main(): | |
def _item(rec: bytes): | |
h, c = rec.split(b':', maxsplit=1) | |
return h.decode(), int(c) | |
# It may seem strange to allow more than 1 persistent connection here, but | |
# actually there is no cost to doing this if it is never used. And it could | |
# be required if the service is re-implemented to use redirects in the | |
# future. We want the command to be responsive even on high latency links | |
limits = httpx.Limits(max_keepalive_connections=15, max_connections=5) | |
with httpx.Client(pool_limits=limits) as cl: | |
while True: | |
try: | |
text = getpass(_prompt) | |
except EOFError: | |
print() | |
return | |
# The API cleverly avoids users revealing to the service exactly | |
# which password they're looking for | |
sha = sha1(text.encode()).hexdigest().upper() | |
url = f'https://api.pwnedpasswords.com/range/{sha[:5]}' | |
try: | |
r = cl.get(url) | |
except BaseException as e: | |
print(f'{url}: {e}') | |
continue | |
# This is a bit wasteful since we keep all results | |
results = dict((_item(x) for x in r.read().splitlines())) | |
cnt = results.get(sha[5:], 0) | |
if cnt: | |
print(f'Password appears {cnt} times') | |
else: | |
print(f'Password is (probably) GOOD!') | |
del results | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment