Password4j/password4j

Argon2 Password validation not working, always showing false

Closed this issue ยท 4 comments

Describe the bug
i have implemented Password Encryption with [password4j/Argon2] .

  • Successfully Encrypted password
  • Password validation not working, always showing false.

To Reproduce
#Step1#: Encryption
Hash hash=Password.hash(userEnteredPassword).addSalt(salt).addPepper(pepper).withArgon2();
#Step2#: Validation
boolean verification=Password.check(userEnteredPassword,hash..toString())
.addSalt(salt))
.addPepper(pepper)
.withArgon2();

 # Details# : 
      userEnteredPassword : yesh599_33 
      salt                                : yesmykaps599
      pepper                          : 80953

#Argon2() Config Details#:
hash.argon2.memory=4096
hash.argon2.iterations=99
hash.argon2.length=128
hash.argon2.parallelism=4
hash.argon2.type=id
hash.argon2.version=20

Expected behavior
Password verification always showing false.

Environment:

  • MAC: [iOS]
  • JDK [Open JDK 11]
  • JVM Character Set (UTF-8)

Additional context
Kindly let me know, if any changes required.

Hello @mykapps599,

just use hash.getResult() instead of hash.toString().

Here you can find a quick guide on the Hash object, but in general Hash#toString() is just a string representation of that object (which contains many information). The hash itself is contained in Hash#getResult()

Using your example:

// Step2: Validation
boolean verification = Password.check(userEnteredPassword, hash.getResult())
                               .addSalt(salt)
                               .addPepper(pepper)
                               .withArgon2();

Also take in account that #addSalt() can be skipped because the salt is already contained in you hash and Password4j automatically parses the hash in search for the salt.
So you can just write

// Step2: Validation
boolean verification = Password.check(userEnteredPassword, hash.getResult())
                               .addPepper(pepper)
                               .withArgon2();

Let me know if you need further information. If not, please close this issue.
Thank you ๐Ÿš€

Hello @mykapps599,

just use hash.getResult() instead of hash.toString().

Here you can find a quick guide on the Hash object, but in general Hash#toString() is just a string representation of that object (which contains many information). The hash itself is contained in Hash#getResult()

Using your example:

// Step2: Validation
boolean verification = Password.check(userEnteredPassword, hash.getResult())
                               .addSalt(salt)
                               .addPepper(pepper)
                               .withArgon2();

Also take in account that #addSalt() can be skipped because the salt is already contained in you hash and Password4j automatically parses the hash in search for the salt. So you can just write

// Step2: Validation
boolean verification = Password.check(userEnteredPassword, hash.getResult())
                               .addPepper(pepper)
                               .withArgon2();

Let me know if you need further information. If not, please close this issue. Thank you ๐Ÿš€

Hello @firaja ,

Thanks for sharing the details.
i have tried below both cases, stil it is showing false only.

  1. boolean verification = Password.check(userEnteredPassword, hash.getResult())
    .addSalt(salt)
    .addPepper(pepper)
    .withArgon2();

  2. boolean verification = Password.check(userEnteredPassword, hash.getResult())
    .addPepper(pepper)
    .withArgon2();

Result: False
Input: Same input as mentioned previously.

Hello @firaja ,

Thanks for sharing the details.
i have tried below both cases, stil it is showing false only.

boolean verification = Password.check(userEnteredPassword, hash.getResult())
.addSalt(salt)
.addPepper(pepper)
.withArgon2();

boolean verification = Password.check(userEnteredPassword, hash.getResult())
.addPepper(pepper)
.withArgon2();

Result: False
Input: Same input as mentioned previously.

@mykapps599 I cannot reproduce your issue.
Can you please execute the following unit test?

    @Test
    public void testFromGithub()
    {
        String userEnteredPassword= "yesh599_33";
        String salt = "yesmykaps599";
        String pepper = "80953";

        Argon2Function argon2 = Argon2Function.getInstance(4096, 99, 128, 4, Argon2.ID, 20);

        Hash hash = Password.hash(userEnteredPassword).addSalt(salt).addPepper(pepper).with(argon2);
        boolean verification = Password.check(userEnteredPassword,hash.getResult()).addSalt(salt).addPepper(pepper).with(argon2);

        Hash rawHash = argon2.hash(userEnteredPassword, salt, pepper);
        boolean rawVerification = argon2.check(userEnteredPassword, hash.getResult(), salt, pepper);

        assertTrue(verification);
        assertTrue(rawVerification);
        assertEquals(rawHash, hash);
        assertTrue(slowEquals(hash.getBytes(), rawHash.getBytes()));
    }

    private boolean slowEquals(byte[] a, byte[] b)
    {
        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++)
        {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }

all the asserts should pass.