SHA1 Hashed User Bulk Import Subsequent Login Failing

I’m unable to log in after importing SHA1 hashed users. I’ve used the management API to bulk import users - in this case I’ve just imported one test user. When I try to log in with the correct password, I see the following error in the logs:
"reason": "Verification failed for the provided custom_password_hash: {'algorithm':'sha1','hash':{'value':'7e5b669a78...','encoding':'hex'},'salt':{'value':'dc539cc4...','encoding':'hex','position':'suffix'}}"

I’m sure I’m missing something simple but as far as I can tell, I’m storing the hash and salt in the correct hex format, the hash and salt are correct according to the logs, and when I verify it with my sample SHA1 hashing script, the password is correct.

I’m using Password123! for this test case.



Bulk import script

import axios from 'axios';
import fs from 'fs';
import FormData from 'form-data';

import 'dotenv/config';

const main = async () => {
    const {
        env: {
            AUTH0_IMPORT_CONNECTION_ID,
            AUTH0_IMPORT_TOKEN,
            AUTH0_IMPORT_URL
        }
    } = process;

    const usersToImportList = JSON.parse(fs.readFileSync('./import-users.json'));

    console.log(`importing ${usersToImportList.length} users...`);

    const form = new FormData();
    form.append('users', fs.createReadStream('./import-users.json'), {
        contentType: 'application/json',
        filename: 'import-users.json'
    });
    form.append('connection_id', AUTH0_IMPORT_CONNECTION_ID);

    const options = {
        method: 'POST',
        url: AUTH0_IMPORT_URL,
        headers: {
            authorization: `Bearer ${AUTH0_IMPORT_TOKEN}`,
            ...form.getHeaders()
        },
        data: form
    };

    try {
        const response = await axios.request(options);

        console.log(response.data);
    } catch (error) {
        console.log(error);
    }
};

main();



Sample user import

[
    {
        "email": "foo@bar.com",
        "email_verified": true,
        "user_id": "123456",
        "blocked": false,
        "custom_password_hash": {
            "algorithm": "sha1",
            "hash": {
                "value": "7e5b669a78bde03d07ac8813ad253e1cd8299a1f",
                "encoding": "hex"
            },
            "salt": {
                "value": "dc539cc4185ce97afbdff9fa8341976f",
                "encoding": "hex",
                "position": "suffix"
            }
        }
    }
]



Sanity check to verify password

import crypto from 'crypto';

const hashPassword = (password, salt) => crypto.createHash('sha1').update(`${password}${salt}`).digest('hex');

const main = () => {
    const inputPassword = 'Password123!';
    const hashedPassword = '7e5b669a78bde03d07ac8813ad253e1cd8299a1f';
    const salt = 'dc539cc4185ce97afbdff9fa8341976f';

    const doesMatch = hashedPassword === hashPassword(inputPassword, salt);

    console.log({
        doesMatch
    });
};

main();