2

I have two md5 hash password that are the same and should return true using the MessageDigest.isEqual method. However the comparison returns false.

When using Array.toString to print the byte-Arrays, they are identical. It still doesn't work, neither for Arrays.euqals nor for MessageDigest.isEqual.

public boolean verifyUserCredentials(String username, MessageDigest password) {

        ListIterator<User> iterator = userList.listIterator();
        while (iterator.hasNext()) {
            User user = iterator.next();
            byte md1[] = user.getPassword().digest();
            byte md2[] = password.digest();
            if (user.getUsername() == username && MessageDigest.isEqual(md1, md2)) {
                return true;
            } 
        }
        return false;
    }
mgrstnr
  • 490
  • 1
  • 5
  • 23

2 Answers2

5

You have used ==, but for objects like String it compares object references to see if they refer to the same object.

To compare String values, use String#equals instead.

rgettman
  • 176,041
  • 30
  • 275
  • 357
0

Alternatively you could take an Evil approach and abuse string interning:

user.getUsername().intern() == username.intern()

the following code prints:

String s1 = "asdf";
String s2 = "as"; // break this into two parts to keep the compiler from 
s2 = s2 + "df";   // automatically interning the constant and having the strings
                  // be the same. 

System.out.println( s1 == s2 ? "true" : "false");
System.out.println( s1.intern() == s2.intern() ? "true" : "false");

Output:

false
true

the +"df" is needed to keep the compiler from automatically interning the constant string.

Note: This is more Java Trivia and Language Abuse than something I would suggest you actually do.

Chris M.
  • 1,731
  • 14
  • 15