Skip to content

Check passwords using haveibeenpwned's k-Anonymity feature

License

Notifications You must be signed in to change notification settings

Syntox32/PwnedPy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PwnedPy

A simple python script and library that uses the haveibeenpwned APIv2 to check if a password or password hash has been pwned using k-Anonymity.

How it works

This module implements the range query from the haveibeenpwned APIv2, which uses k-Anonymity to better secure the hash you are requesting results for.

It works like this: Only the first 5 characters from the SHA-1 hash is sent to the server. The server then responds with hashes that matches the prefix. The hashes the server send back all have the first 5 chars cut away. The hashes are then assembled using the prefix and suffix, locally, to check if the password matches the one you provided.

You can read the blog post on this by the site's developer, here

Is it secure?

1Password has implemented this in their service, so go make up your own opinion. You should of course always be skeptical of where you punch in your password. You should also read the source code.

CLI Usage

$ python3 ./main.py --help
usage: main.py [-h] [--password PWD] [--hash PWDHASH]

Check if a password has been pwned using the haveibeenpwned APIv2.

optional arguments:
  -h, --help            show this help message and exit
  --password PWD, -p PWD
                        Password to check, in cleartext.
  --hash PWDHASH        Password to check, as a SHA-1 hash.

Example Usage

$ python3 ./main.py
Password:
$ python3 ./main.py --password "test"
$ python3 ./main.py --password test
$ python3 ./main.py --p "test"
$ python3 ./main.py --hash a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

All of the above will give this result:

There was a match, go change your password!
Seen # times in the database: 68340

If there was no match found:

No match.

Using the module

Import the Pwned class.

from pwnedpy import Pwned, RateLimitException

Use the functions check and check_hash.

Both check and check_hash return the full hash and the number of time the password has been seen in the database, if it was a match.

h, count = p.check(pwd)

If there was no match, the functions return None and 0, respectively.

Example usage (from main.py)

(...)
args = parser.parse_args()
p = Pwned()
try:
    if not args.pwd and not args.pwdhash:
        pwd = getpass.getpass("Password: ")
        h, count = p.check(pwd)

    elif args.pwd:
        h, count = p.check(args.pwd)

    elif args.pwdhash:
        h, count = p.check_hash(args.pwdhash)

    if h:
        print("There was a match, go change your password!")
        print("Seen # times in the database: {}".format(count))
    else:
        print("No match.")

except RateLimitException as e:
    print("You're being rate-limited.")
except Exception as e:
    print("Error: {}".format(e))

TODOs

  • Implement the rest of the REST APIv2

Requirements

The script has only been tested with Python 3.6.4, it should work down to Python 3.4.x.

requests is the only other requirement. Install with pip install -r Requirements.txt, or pip install requests.

License

The code is licensed under an MIT license.

About

Check passwords using haveibeenpwned's k-Anonymity feature

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages