4

I have checked this forum and the docs, but found no answer to this question, that is, how can I do a basic Spring Security configuration setup using a basic java Object as a salt for MD5 encoding?

Here is my Spring Security context snippet configuration:

  <beans:bean id="saltSource" class="com.myproject.sec.util.MyString" scope="singleton" >
      <beans:constructor-arg value="12345" />
  </beans:bean>

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source ref="saltSource" />
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

...but this configuration throws an unwanted error Exception complaining that the Salt source is not of org.springframework.security.authentication.dao.SaltSource interface, but I do not want to use a property of User details as my salt (as this interface supports User Details), but rather my custom String Object as demonstrated above. How do I do achieve this?

Also, as a second closely related question, I know I can get the Salt as the Username like this:

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source user-property="username"/>
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

and, have a system wide fixed Salt of "12345" like this:

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source system-wide="12345"/>
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

...but how do I get the Salt as a concatenation of both the Username and system wide constant of "12345", e.g., if the username is fred, to have the Salt as "fred12345" without resorting to overriding to implement my own Encoding?

Cem Sultan
  • 354
  • 2
  • 12

3 Answers3

2

Please don't use MD5 to hash passwords, it is very easy to crack.

Use Spring Security's newish BCryptPasswordEncoder. It handles salting for you (and stores the hash and salt in the same db column):

http://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html

Here's my answer on the easy way to do it:

Spring Security with roles and permissions

Community
  • 1
  • 1
Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
  • Thanks for the info. I am going to give this answer a tick, but may I ask: (1) why it's easy to hack MD5 if a unique concatenation Salt (as described above) is used? (2) If I did decide to use MD5 for certain reasons, is it possible (without overriding) to pass a unique Salt (username + MyString object) to MD5 encoded via Spring Security configuration context file, and if so, how? – Cem Sultan Oct 03 '13 at 14:03
  • Here's some data on speed of cracking fast hashes: http://security.stackexchange.com/questions/8607/how-quickly-can-these-password-schemes-really-be-beaten – Krešimir Nesek Oct 03 '13 at 17:07
2

If you want salt to be username + "12345", you can implement your own SaltSource (it's easy):

public class UserNameAndStringSalt implements SaltSource {
    @Override
    public Object getSalt(UserDetails user) {
        return user.getUsername() + "12345";                
    }
}

And then:

<beans:bean id="saltSource" class="com.myproject.UserNameAndStringSalt" scope="singleton" />

<authentication-manager alias="authenticationManager">
  <authentication-provider user-service-ref="userService">
      <password-encoder hash="md5">
          <salt-source ref="saltSource" />
      </password-encoder>
  </authentication-provider> 
</authentication-manager>

And as Neil McGuigan said in answer above, try not to use MD5 or single-pass SHA - it's better to use BCrypt or SCrypt for reasons stated here: https://security.stackexchange.com/questions/8607/how-quickly-can-these-password-schemes-really-be-beaten

Community
  • 1
  • 1
Krešimir Nesek
  • 5,302
  • 4
  • 29
  • 56
  • 1
    Thanks for your post, but I was looking how to achieve this without resorting to implementing my own Salt Source, but to able to do it via the Spring Security configuration context file if possible. – Cem Sultan Oct 03 '13 at 18:51
0

It's recommended to use the StandardPasswordEncoder that spring security provides. It will automatically handle the salting for you. It also uses a much stronger SHA256 hash.

http://docs.spring.io/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/crypto/password/StandardPasswordEncoder.html

<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder ref="passwordEncoder" />   
    </authentication-provider>
</authentication-manager>
Bart
  • 17,070
  • 5
  • 61
  • 80
  • Using BCryptPasswordEncoder has a default of 10 rounds, which can be easily set to any number (e.g. 1024) via it's constructor in addition to having a SecureRandom instance for hashing. It implements the _PasswordEncoder_ interface, which states that it will use SHA-1 or greater hash combined with an 8-byte or greater randomly generated salt. Using StandardPasswordEncoder has SHA-256 hashing with 1024 iterations and 8-byte random salt value together with a Secret value. So, what hashing algorithm does BCryptPasswordEncoder use? And which of these 2 is more solid against a possible hack? – Cem Sultan Oct 03 '13 at 21:30
  • I didn't notice the @neilmcguigan until after I posted my answer. Looking into it, BCryptEncoder is the better one to use (it even says so in the source code of StandardPasswordEncoder). BCrypt is not a hash algorithm but a [key derivation function (KDF)](http://en.wikipedia.org/wiki/Key_derivation_function). It uses Blowfish under the cover. What I really find interesting is that bcrypt is adaptive. Which means you can increase it's strength in the future to make it more costly to crack. – Bart Oct 04 '13 at 07:15