Skip to content

havibeenpwnd

https://www.youtube.com/watch?v=hhUb5iknVJs

This site has an api to check if you password has been pwnd without compromising the password itself. It has a database of breached passwords of about 550.000.000 passwords.

You just hash your password with sha1

sha1 hash
echo -n "secret" | sha1sum | awk '{print S1}
e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4  -

The -n prevents echo from outputting a trailing newline, which would give you a different has completely. The awk command is there to remove a trailing - from the sha1sum output.

You just pass the first 5 characters of this hash and search on the api :

test your hash
curl https://api.pwnedpasswords.com/range/E5E9F > dmp

You will get a lot of entries, but the list is now short enough to search for your hash and see if it is there.

You need to lowercase the output for searching and also keep in minds the 5 characters you provided are not included in the hashes.

And indeed you will find that secret is found 350 thousand times in breaches.

found
a1ba31ecd1ae84f75caaa474f3a663f05f4:352091

script

The website shows an python script that does this better, i include it here fully. Simply run 'python3 pwnd.py' and test all your passwords.

test script from computerphile
#!/usr/bin/env python
import hashlib
import sys

try:
    import requests
except ModuleNotFoundError:
    print("###  pip install requests  ###")
    raise

def lookup_pwned_api(pwd):
    sha1pwd = hashlib.sha1(pwd.encode('utf-8')).hexdigest().upper()
    print(sha1pwd)
    head, tail = sha1pwd[:5], sha1pwd[5:]
    url = 'https://api.pwnedpasswords.com/range/' + head
    res = requests.get(url)
    if not res.ok:
        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

def main(args):
ec = 0
for pwd in args or sys.stdin:
    pwd = pwd.strip()
    try:
        sha1pwd, count = lookup_pwned_api(pwd)
    except UnicodeError:
        errormsg = sys.exc_info()[1]
        print("{0} could not be checked: {1}".format(pwd, errormsg))
        ec = 1
        continue

    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))
return ec

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))