user1154644
user1154644

Reputation: 4609

Credentials are incorrect when using hashed passwords

I am trying to store user passwords using sha 256 encryption. I have the following method to encrypt passwords:

    public static String hashPassword(String password) {
       MessageDigest mdEnc = null;
       try {
         mdEnc = MessageDigest.getInstance("SHA-256");
       }  catch (NoSuchAlgorithmException e) {
        return null;
       }
       mdEnc.update(password.getBytes(), 0, password.length());

       return new BigInteger(1, mdEnc.digest()).toString(16);
}

I have the following declared in my security domain, but every time I try to login, it says the credentials are incorrect. When I don't use encryption, and remove the hashAlgorithm and hashEncoding properties, and store the passwords in the clear, authentication works fine. Can anyone see any problem with my encryption method?

<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="base64"/>

I tried to follow an example that had a straightforward encryption method:

import org.jboss.security.auth.spi.Util;

public class PasswordGenerator {
   public static void main(String[] args) {
     for (String arg : args) {
        System.out.println(new PasswordGenerator().generate(arg));
     }
    }
   private String generate(String password) {
     return Util.createPasswordHash("SHA-256", "BASE64", null, null,password);
   }
}

The problem is that it says that the jar that contains the Util class was in the module directory of the JBoss installation, but it must have been an older example because I don't see it.

Upvotes: 0

Views: 212

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

Your issue is using the BigInteger to create the hexadecimal encoding; BigInteger can be created using big endian encoding in a byte array. However, if the byte array starts with one or more 00 valued bytes, then these bytes may be stripped. Use Guava, Apache Codec or Bouncy Castle to create a hexadecimal string instead.

That said, you should use a password based key derivation function (PBKDF) such as PBKDF2 (present in the standard Java API), bcrypt or scrypt to store password "hashes". These output bytes as well, so if you require text, you will still need to encode it.

Also note that String.getBytes() uses the platform encoding, which you should only use to communicate with the standard. Instead, you should supply a character encoding to String.getBytes() method, e.g. use String.getBytes(StandardCharsets.UTF_8).

Upvotes: 1

Related Questions