Importing Password Hashes from Drupal 7

Making progress but still bamboozled

  1. That SO post, when it talks about bytes in the pass it means characters in the base64 encoded password so if the content of the users.pass field is

$S$D.oOkSJYpbtcVkh1QWSm8BzRKYpsEHrrqPRiaDmiqr.GVE3QisdC

Then
settings is ‘$S$D’
salt is ‘.oOkSJYp’
hash is ‘btcVkh1QWSm8BzRKYpsEHrrqPRiaDmiqr.GVE3QisdC’

  1. The Drupal in-code comments say that a base64 encoded sha512 password is always 86 characters but all the examples generated by my Drupal 7 system are 55 characters

  2. the hash values split out of the pass field are rejected by auth0 because they are not a multiple of 4 characters. If I round trip the salt and hash through a node buffer it becomes acceptable to auth0 but still doesn’t allow the correct password to validate

  3. the Drupal _password_crypt function uses the 4th character of the settings as a log2 loop counter to hash the hash with itself. I don’t see how auth0 can be compatible with this unless there is a field to pass the loop count in. So in my example the character is D meaning 4.

  4. finally, nodejs and php seem to handle base64 differently. There are ‘.’ characters in the php base64 strings which are eliminated by round-tripping through a node Buffer.

in case it’s any use here is my current code, but it isn’t right.

function fixBase64(s) {
  return Buffer.from(s, 'base64').toString('base64');
}

function convert({ mail, pass }) {
  const setting = pass.slice(0, 12);
  const salt = setting.slice(4);
  const hash = pass.slice(12);
  return {
    "email": mail,
    "email_verified": true,
    "custom_password_hash": {
        "algorithm": 'sha512',
        "hash": {
            "value": fixBase64(hash),
            "encoding": "base64"
        },
        "salt": {
            "value": fixBase64(salt),
            "position": "prefix",
            "encoding": "base64"
        }
    }
  };
}