Wildfly digest login-config with database login module

encryption, jaas, java, wildfly-8

Solution

Looking at the source code, I see the following happening:

- The input user password is hashed/encoded because `hashUserPassword` is set to `true` and the algorithm and encoding are provided.

- The password retrieved from the database is hashed/encoded because `hashStorePassword` is set to `true` and the algorithm and encoding are provided.

- The two hashed/encoded passwords are compared.

Now, if your database already contains the hashed/encoded password (which I assume), this means that the one retrieved from the database will be doubly hashed/encoded, and the comparison with the user-provided one will fail.

The solution would then be to change the `hashStorePassword` option to `false` like this:

<module-option name="hashStorePassword" value="false"/> 

Problem

I try to encrypt password in database login module with Wildfly picketbox module. These are my sources. == web.xml ``` ... <security-role> <role-name>administrator</role-name> </security-role> <login-config> <auth-method>DIGEST</auth-method> <realm-name>WildFly8DigestRealm</realm-name> </login-config> .... ``` == jboss-web.xml ``` ... <jboss-web> <security-domain>java:/jaas/my_secure_domain</security-domain> </jboss-web> ``` == standalone.xml ``` ... <security-domain name="my_secure_domain" cache-type="default"> <authentication> <login-module code="Database" flag="required"> <module-option name="dsJndiName" value="java:jboss/datasources/MySqlDS"/> <module-option name="principalsQuery" value="select password from credential where uid=?"/> <module-option name="rolesQuery" value="select urole, 'Roles' from credential where uid=?"/> <module-option name="hashAlgorithm" value="MD5"/> <module-option name="hashEncoding" value="base64"/> <module-option name="hashUserPassword" value="true"/> <module-option name="hashStorePassword" value="true"/> </login-module> </authentication> </security-domain> ``` Password is encrypted with below == EncryptPassword.java ``` import java.security.MessageDigest; import org.jboss.security.Base64Encoder; public class EncryptPassword { public static void main(String[] args) { // TODO Auto-generated method stub String algoritmo = "MD5"; String clearTextPassword = "passwd123"; String hashedPassword = null; try { byte[] hash = MessageDigest.getInstance(algoritmo).digest(clearTextPassword.getBytes()); hashedPassword = Base64Encoder.encode(hash); System.out.println("Clear Text Password : " + clearTextPassword); System.out.println("Encrypted Password : " + hashedPassword); } catch (Exception e) { e.printStackTrace(); } } } ``` And also I executed Java command on shell like below as well as above Java file: C:>java -cp c:\wildfly-8.0.0.final\modules\system\layers\base\org\picketbox\main\picketbox-4.0.20.Final.jar org.jboss.security.Base64Encoder passwd123 MD5 Both result brings the same hashed password and hashed password is updated. ``` Clear Text Password : passwd123 Encrypted Password : EWT55bjO92g5bc1TdOS26w== ``` However, login is still failed. And in server.log it throws the following exception. ``` LoginModule Class: org.jboss.security.auth.spi.DatabaseServerLoginModule ControlFlag: LoginModuleControlFlag: required Options: name=hashUserPassword, value=true name=hashAlgorithm, value=MD5 name=principalsQuery, value=select password from credential where uid=? name=hashEncoding, value=base64 name=dsJndiName, value=java:jboss/datasources/MySqlDS name=hashStorePassword, value=true name=rolesQuery, value=select urole, 'Roles' from credential where uid=? 2014-07-15 21:06:45,845 TRACE [org.jboss.security] (default task-2) PBOX000236: Begin initialize method 2014-07-15 21:06:45,845 DEBUG [org.jboss.security] (default task-2) PBOX000281: Password hashing activated, algorithm: MD5, encoding: base64, charset: null, callback: null, storeCallBack: null 2014-07-15 21:06:45,846 TRACE [org.jboss.security] (default task-2) PBOX000262: Module options [dsJndiName: java:jboss/datasources/MySqlDS, principalsQuery: select password from credential where uid=?, rolesQuery: select urole, 'Roles' from credential where uid=?, suspendResume: true] 2014-07-15 21:06:45,847 TRACE [org.jboss.security] (default task-2) PBOX000240: Begin login method 2014-07-15 21:06:46,022 TRACE [org.jboss.security] (default task-2) PBOX000263: Executing query select password from credential where uid=? with username admin 2014-07-15 21:06:46,037 DEBUG [org.jboss.security] (default task-2) PBOX000283: Bad password for username admin 2014-07-15 21:06:46,037 TRACE [org.jboss.security] (default task-2) PBOX000244: Begin abort method 2014-07-15 21:06:46,037 DEBUG [org.jboss.security] (default task-2) PBOX000206: Login failure: javax.security.auth.login.FailedLoginException: PBOX000070: Password invalid/Password required at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:284) [picketbox-4.0.20.Final.jar:4.0.20.Final] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_60] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_60] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_60] at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688) [rt.jar:1.7.0_60] at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:687) [rt.jar:1.7.0_60] at javax.security.auth.login.LoginContext.login(LoginContext.java:595) [rt.jar:1.7.0_60] ```

Original source