Importing Password Hashes from Drupal 7

OK, I’ve translated Drupal 7’s password.inc file into commonJS module here.

It now correctly identifies correct passwords from the database pass field.

I’ve added a _password_base64_decode function which correctly reverses the Drupal 7 _password_base64_encode function and this round trips correctly. (This isn’t intended to be production code - its very brute force).

I’ve created auth0 user imports from this by using my _password_base64_decode function separately on the hashed password and the hashed salt fields and then encoding these to hex. These import successfully.

But, as I expected, I still get wrong password errors when I log in using the imported user and the correct password.

I think I’ve eliminated all other possible errors and the problem must now be that auth0 does not support stretching the hash.

I think to support Drupal 7 import we need to add an iterations field to the custom_password_hash object and implement the stretching functionality.

The code is:

count = 1 << count_log2;
  const pb = Buffer.from(password);
  do {
      hash = crypto.createHash(algo);
      hash.update(Buffer.concat([buffer, pb]));
      buffer = hash.digest();
  } while (--count);

as in lines 184 to 190 in my gist.

count_log2 is 15 in current Drupal 7 configurations and signalled in the settings as the ‘D’ in ‘$S$D’.

This is what my convert function looks like now with an assumed log2_iterations field:

const drupal = require('./password');

function convert({ mail, pass }) {
  const settings = pass.slice(0,4);
  const hashedSalt = pass.slice(4,12);
  const hashedPass = pass.slice(12);
  const salt = drupal._password_base64_decode(hashedSalt);
  const hash = drupal._password_base64_decode(hashedPass);
  const log2_iterations = settings.charCodeAt(3)-53;
  return {
    "email": mail,
    "email_verified": true,
    "custom_password_hash": {
        "algorithm": 'sha512',
        log2_iterations,
        "hash": {
            "value": hash.toString('hex')
        },
        "salt": {
            "value": salt.toString('hex'),
            "position": "prefix",
        }
    }
  };
}

FYI the Drupal folks pointed me at this link which describes the stretching.