Merge pull request #2 from mina86/master

Various improvements
This commit is contained in:
Michael Pound 2019-03-13 10:35:36 +00:00 committed by GitHub
commit 2bea07cee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 26 deletions

View File

@ -3,6 +3,13 @@ Pwned Password API lookup
Usage: Usage:
python pwned.py [password] * `python pwned.py` reads passwords from standard input;
* `pytohn pwned.py <[file-with-passwords]` reads passwords from
a file;
* `another-command | pytohn pwned.py <[file-with-passwords]` reads
passwords written to standard output by another command;
* `python pwned.py [password]` checks passwords given as command line
arguments (beware the password may be saved in shell history and that
other users on the system ma be able to observe the command line).
Have fun! Oh, and if you find one of your own passwords, change it asap! Have fun! Oh, and if you find one of your own passwords, change it asap!

View File

@ -1,35 +1,48 @@
import hashlib
import requests import requests
import cryptography
from base64 import b16encode
import sys import sys
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
def hash_password_sha1_hex(pwd):
digest = hashes.Hash(hashes.SHA1(), backend=default_backend())
digest.update(pwd.encode('ASCII'))
sha1 = b16encode(digest.finalize()).decode('ASCII')
return sha1
def lookup_pwned_api(pwd): def lookup_pwned_api(pwd):
sha1pwd = hash_password_sha1_hex(pwd) """Returns hash and number of times password was seen in pwned database.
head = sha1pwd[:5]
tail = sha1pwd[5:]
r = requests.get('https://api.pwnedpasswords.com/range/{0}'.format(head)) Args:
if r.status_code == 200: pwd: password to check
hashes = (s.split(':') for s in r.text.split('\r\n'))
pred = ((head + t,count) for t,count in hashes if t == tail)
password_hit = next(pred, None) Returns:
return password_hit 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.
Raises:
RuntimeError: if there was an error trying to fetch data from pwned
database.
"""
sha1pwd = hashlib.sha1(pwd.encode('ascii')).hexdigest().upper()
head, tail = sha1pwd[:5], sha1pwd[5:]
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))
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
api_return = lookup_pwned_api(sys.argv[1]) def main(args):
if (api_return): ec = 0
print (sys.argv[1], "was found") for pwd in args or sys.stdin:
print ("Hash {0}, {1} occurences".format(api_return[0], api_return[1])) pwd = pwd.strip()
sha1pwd, count = lookup_pwned_api(pwd)
if count:
print(pwd, "was found")
print("Hash {0}, {1} occurrences".format(sha1pwd, count))
ec = 1
else: else:
print (sys.argv[1], "was not found") print(pwd, "was not found")
return ec
exit()
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))