API Documentation

Please note: This API and services are provided "as is". If you find this service useful and want to integrate it into your account management workflows, please contact GWDG Support for details.

This HTTP API for this service is mostly compatible with the haveibeenpwned.com "Search by range" API, with some minor changes (see below). To check a password against the database, send a GET request to /range/{prefix}, where {prefix} is replaced with the first 5 characters of the hashed password (SHA-1, hexadecimal, upper-case). The actual password or its unsalted hash are never exposed to the API server and remain private.

The server will return a plain-text list of hash-suffixes matching the given prefix, and a badness-score for each hash, separated by a single colon character. This list can be searched for a specific hash-suffix on client side.

To check NTLM hashes instead of SHA-1, simply add ?mode=ntlm to the end of the URL. This is particularly useful for checking existing passwords stored in ActiveDirectory, as those can be extracted as unsalted NTLM hashes and checked directly against this API without knowing the actualplain-text password.

Example (curl):

$ curl -s https://pwcheck.gwdg.de/range/E576D
00310CF0174585D345D6F6EA3C222ACB4FC:8
00A2B90A2D77DCEBF61BB898F797036D417:1
00E4651919DEDE3CFD3BECFAEB0B9B78824:6
...

Differences from the haveibeenpwned.com API:

Script Examples

The following scripts may serve as a starting point for client development or local tests.

Example (bash):

$ PWHASH=$(echo -n "password" | sha1sum | cut -b 1-40 | tr '[:lower:]' '[:upper:]')
$ PREFIX=$(echo $PWHASH | cut -b 1-5)
$ SUFFIX=$(echo $PWHASH | cut -b 6-40)
$ curl -s https://pwcheck.gwdg.de/range/$PREFIX | fgrep $SUFFIX
1E4C9B93F3F0682250B6CF8331B7EE68FD8:3713105

Example (python):

import hashlib, urllib.request

password = "password"
pwhash = hashlib.sha1(password.encode('utf8')).hexdigest().upper()
prefix = pwhash[:5]
suffix = pwhash[5:]

url = "https://pwcheck.gwdg.de/range/" + prefix
with urllib.request.urlopen(url) as response:
  for line in response.read().splitlines():
      line = line.decode('ASCII')
      if line.startswith(suffix):
          print("Bad password!", "Score:", line.split(':')[-1])

Contact

This service is provided by Gesellschaft für wissenschaftliche Datenverarbeitung mbH for testing purpose only. If you find this service useful, please contact GWDG Support. Imprint: https://www.gwdg.de/impressum.