Bulk User Import of pbkdf2-whirlpool hashed passwords

Hi,

I am trying to test user import to see if our database can be migrated to auth0 without the need for the customers to change passwords.

Our salts are lowercase hex strings of the length 128
Our hashes are created by php 8.2’s hash_pbkdf2(‘whirlpool’, password, salt, 100000)

Given a random salt

0fcf8ad37d20a4fb32d5e56a7c268511bbe5631962c21267443bc90b95ebdfe136997c1e3c185bfbd1d42a1c4990dd0bcafff5519480696813a8c1fe75ffd9bf

And a password ‘password’

The php delivers following hash:

982133e7e9e7bbf8e6582bc4b3659f7b02dfdfcefbc9c7c31d490b8f10f455344fed9fbc35311f10f4856cad5cce28b4fb70da8ef80e905127813f5e4dcc39fc

According to the documentation, the slat and hash have to be base64 encoded with padding = removed.
I then base64 the hash and the salt by chunking the strings into character sequences of length 2, mapping them to int and getting a byte array of the result.

Base64.encode(string.chunked(2).map { it.toInt(16).toByte() }.toByteArray())
                .trimEnd('=')

I send a post request to the api/v2/users-imports with the hash.value string as follows:

"$pbkdf2-whirlpool$i=100000,l=128$<salt>$<hash>"

The user is successfully imported but I cannot login with the following error in the logs:

"reason": "Verification failed for the provided custom_password_hash: {'algorithm':'pbkdf2','hash':{'value':'$pbkdf2-whirlpool$i=100000,l=128$D8+K030gpPsy1eVqfCa...'},'salt':{'value':''}}"

I have seen many similar issues but could not solve my problem. Does anybody have suggestion for me what I could try?

1 Like

I have tried different lengths (0,32,64,128,256), leaving the parameters completely out, using string.toByteArray() directly, reversing the chunked string, skipping base64 encoding, to no avail

1 Like

We have found a solution, if anyone is interested. PHP’s hash_pbkdf2 treats salt string not a string containing hex values, it just converts it to bytes - same as what you would get in kotlin by doing string.toByteArray. So in order to correctly convert it to Base64 in our application, we needed to do:

Base64.encode(string.toByteArray()).trimEnd('=')

This only applies to salt, the password hash base64 transformation stays as in original post

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.