Hashed Credentials API

Check compromise status for a username/password combination using a secure, k-anonymity hash-based approach

TO DRAMATICALLY SIMPLIFY THE PROCESS OF CALLING THIS API, WE STRONGLY RECOMMEND USING ONE OF OUR LIBRARIES.

The Hashed Credentials API allows you to securely query the Enzoic credentials database without passing the raw credentials.

Using the Hashed Credentials API is a multi step process, as follows:

  1. Retrieve the Account Salt and Hashes Make a GET call to the /accounts API endpoint with desired email address or a SHA256 hash of the email address. This will return a salt value, as well as an array of Password Hash Specifications containing hash types (hashing algorithms and when required salts). If this call returns a 404, it indicates that we have no compromised credentials for this email address and you can skip the remaining steps.

  2. Calculate Requested Password Hashes For each entry in the returned hashes array, construct a hash of the user’s password using the specified hashing algorithm and salt value. See the table of hash algorithms here for reference: hash types

  3. Calculate Credential Hashes For each resultant password hash from step 2, construct a credentials hash by concatenating the username and password together, and then calculating an Argon2 hash of the result using the Account salt returned in step 1.

  4. Make Credentials API Call Make a GET call to the /credentials API endpoint with the array of Argon2 hashes from step 3. The result will indicate whether the credentials have been compromised.

More detail for each step follows below.

Step 1 – Retrieve the Account Salt and Hashes

The first step is to make a GET call to the /accounts API endpoint to retrieve the account-specific salt value and a list of required hashes. The /accounts call is as follows:

Step 2 – Calculate the Requested Password Hashes

Next, iterate over the passwordHashesRequired array returned in step 1, calculating a password hash as specified by the hashType of each entry.

HashTypes

Some of the hashTypes are standard hashing algorithms, such as SHA-1 and BCrypt, while others are composite algorithms, combining the password, salt, and potentially multiple standard hashes together to calculate a final hash value. For example, hashType 5 is a composite with the following algorithm: md5(md5(salt) + md5(password)). Thus, it would be necessary to calculate an MD5 of the provided salt and concatenate this with an MD5 of the password. Finally, an MD5 of the resultant string is calculated and this is the final hash. Unless otherwise specified, the standard hash steps in a composite algorithm should all be output to lowercase hex string representations of the value.

Salts

Note that some of the hashTypes require salt values and some do not, depending on the hash algorithm. When the salt value is not required for the specified algorithm, it will be an empty string.

Hash Libraries

Calculating these hashes will involve language-specific libraries to provide standard hashing functions (MD5, SHA-1, SHA-256, etc). Typically these functions are either built-in or available as open-source libraries for practically any widely-used programming language.

Step 3 – Calculate the Credential Hashes

For each item in the password hashes array produced in step 2, concatenate the username and password hash and then hash the result with the Argon2 algorithm and the account salt returned in step 1. Lastly, extract just the hash value from the Argon2 hash (the string will also contain the algorithm hash parameters and salt value used). This should result in an array of Credential Hashes, which will be the arguments passed to the Credentials API in the final step.

Example:

for (var i = 0; i < passwordHashes.length; i++) { 
  // concatenate the username, "$", and password hash value from step 2 into a single string
  var toHash = username + "$" + passwordHashes[i];
 
  // calculate the Argon2 hash (Argon2 library for your programming language required)
  var argon2Hash = Argon2(toHash, accountSalt);
 
  // extract just the hash value from the resultant Argon2 string (should be everything after the last "$"
  credentialHashes[i] = argon2Hash.substr(argon2Hash.lastIndexOf("$") + 1);
}

When calculating the Credential Hash, the Argon2 algorithm should be called with the following settings:

SettingValue

Type

Argon2d

Iterations/TimeCost

3

Memory

1024

Parallelism

2

HashLength

20

Step 4 – Make the Credentials API Call

The final step is to make a GET call to the /credentials API endpoint, passing in a list of the first 10 hex characters from each Credential Hash calculated in step 3. Note that many Argon2 libraries will return a hash result in Base64, so it may be necessary to convert the hash into a hex string before extracting the first 10 characters. The /credentials call in this case is as follows:

Test Accounts

Test accounts are available to help verify implementation:

pageTest Accounts

Last updated