How do I replicate the hashes in the Nextcloud database?

So I’m trying to find out how the Nextcloud password system works to replicate the results of what are in my database. Sample:

2|$argon2i$v=19$m=65536,t=4,p=1$UDBJTVFJRlJNeG5FOVkuNg$DU1g2hV1fX/YhRG6Pq9BXuA+3wj7qX6GjZvYYOclkRg

As far as I know, the 2| means that the algorithm is argon2i but I don’t know where to go from here to turn the password into the exact hash as shown above. I’m trying to use a web tool to replicate the hash but I don’t know what parameters to give it (the salt, memory, iterations, hash length, and parallelism).

If anyone could give me like a simple procedure to replicate the same hashes I would really appreciate it. Thanks!

The generated salt and hash will be never the same.
Try this in a php shell:

dev@dev-tuxedo:~$ php -a
Interactive shell

php > $myPlainPassword = 'test';
php > $hashOptions = ['memory_cost'=>65536, 'time_cost'=>4, 'threads'=>1];
php > $myFirstHashedPassword = password_hash($myPlainPassword, PASSWORD_ARGON2I, $hashOptions);
php > var_dump($myFirstHashedPassword);
php shell code:1:
string(96) "$argon2i$v=19$m=65536,t=4,p=1$NFFnaHJHWEE3SFlkbTRLUg$G7fYWLPW1uuE90qc20uR2aOLOQs/LjkTN4b9N0wjP9s"
php > $mySecondHashedPassword = password_hash($myPlainPassword, PASSWORD_ARGON2I, $hashOptions);
php > var_dump($mySecondHashedPassword);
php shell code:1:
string(96) "$argon2i$v=19$m=65536,t=4,p=1$NG5IcFBnNGh1OVlHWTl2TA$uIWw8FPCxIrJVOEnnqU0VApUgDIzNLtbs5I8VKJSFPs"

But both generated hashes are valid, if you verify the plain password string against the two previously generated hash strings.

php > var_dump(password_verify($myPlainPassword, $myFirstHashedPassword));
php shell code:1:
bool(true)
php > var_dump(password_verify($myPlainPassword, $mySecondHashedPassword));
php shell code:1:
bool(true)

So to answer your question, you can’t replicate (regenerate) an specific hash.
The hashes are always randomized.

References:
function password_hash()
function password_verify()

1 Like

Sorry, i have to correct myself.
It is still possible to pass the salt as a hash option to argon2i.
But it is deprecated since PHP 7.0 and was ignored in a PHP 8.0 sandbox test.

Following hash options should work under PHP 7.2 - 7.4 to generate your example hash:

$plainPassword = '???';
$hashOptions = [
	'memory_cost' => 65536,
	'time_cost' => 4,
	'threads' => 1,
	'salt' => base64_decode('UDBJTVFJRlJNeG5FOVkuNg') // deprecated, ignored in php 8.0
];
$hashedPassword = password_hash($plainPassword, PASSWORD_ARGON2I, $hashOptions);