Reputation: 4609
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
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