1

I am using the Spring Roo framework which uses Spring Security as security framework. I configured it the following way:

<authentication-manager alias="authenticationManager">
    <!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
    <authentication-provider>
        <password-encoder hash="sha-256">
            <!-- <salt-source user-property="login"/> -->
        </password-encoder>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="
            SELECT login, password, enabled
            FROM user WHERE login = ?"

            authorities-by-username-query="
            SELECT u.login, r.authority
            FROM user u, rol r, 
            usuer_role ur
            WHERE u.login = ur.usuarer
            AND r.roleId = ur.role
            AND u.login = ?"        
        />
        <user-service>
            <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN" />
            <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>

In order to make the passwords match I edited the UserController create method so the password is stored applying a SHA-256 hash, the same that was configured in applicationContext-security.xml which is the security configuration file.

This is how I do it:

public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    if (bindingResult.hasErrors()) {
        populateEditForm(uiModel, usuario);
        return "security/users/create";
    }
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(user.getPassword().getBytes("UTF-8"));
    byte[] digest = md.digest();
    usuario.setPassword( new String(digest, "UTF-8"));
    uiModel.asMap().clear();
    user.persist();
    return "redirect:/security/users/" + encodeUrlPathSegment(usuario.getId().toString(), httpServletRequest);
}

I tried setting the password to admin which is the same provided for the default user: admin, password: admin by the configuration file in order to check that the password generated by my create method matches.

However, the hashed password in the configuration file is 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 but the one stored in the database is a weird set of characters when I inspect my mysql database via console or ivAMgsKo*H when displayed in a page.

Any help?

dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • The output of SHA-256 is not UTF-8 encoded text. Seems like you want to use base64 encoding to convert the `byte[]` digest into a string instead of `new String(digest, "UTF-8")`. – Oleg Estekhin May 20 '14 at 10:14
  • I did this byte[] `digest = Base64.encodeBase64(md.digest()); user.setClave(new String(digest));` but now the password is `jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg=` not `8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918` – dabadaba May 20 '14 at 10:52
  • 1
    My bad, you need to use [hex encoding](http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java) instead of your initial attempt at UTF-8 or my initial suggestion for Base64. – Oleg Estekhin May 20 '14 at 10:56
  • You shouldn't be using SHA as a password hash - it's a very poor choice. Just try typing the hash value into google for example and you will instantly [find the password](http://md5-database.org/sha256/admin). Use [bcrypt instead](http://stackoverflow.com/questions/8521251/spring-securitypassword-encoding-in-db-and-in-applicationconext/8528804#8528804). – Shaun the Sheep May 20 '14 at 11:53

2 Answers2

4

Finally I came up with this solution, thank to @Oleg Estekhin comment:

public String sha256(String original) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(original.getBytes());
    byte[] digest = md.digest();
    return new String(Hex.encodeHexString(digest));
}
dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • 1
    Instead of `Hex.encodeHexString` you can use `DatatypeConverter.printHexBinary(digest)` from `import javax.xml.bind.DatatypeConverter;`. – Brent Bradburn Feb 02 '18 at 17:54
-1

However, the hashed password in the configuration file is 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 but the one stored in the > database is a weird set of characters when I inspect my mysql database via console or ivAMgsKo*H when displayed in a page.

8c6976e5b541041... 

looks like a Base64 encoded data.

While

 ivAMgsKo*H

and your code

new String(digest, "UTF-8")

tells me, that your digest is not encoded but stored as a UTF-8 string.

A hash value can contain not printable byte values, so it is common to encode the value. For example with Base64.

wdick
  • 99
  • 4