Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31215

Custom password salts with Spring security

I want to hash & salt user passwords with bcrypt and Spring security.

Here is my User model (I removed useless code) :

public class User {
  private Integer id;
  private String email;
  private String hashedPassword;
  private String salt; //I want to use this salt.
  private Boolean enabled;

  //Getters & Setters
}

Here is how I create new users with their own salt :

@Transactional
public User create(String email, String password) {
  User user = new User();
  user.setSalt(BCrypt.gensalt(12)); //Generate salt
  user.setEnabled(true);
  user.setEmail(email);
  user.setHashedPassword(BCrypt.hashpw(password, user.getSalt()));
  return dao.persist(user);
}

And here is the spring configuration :

<beans:bean id="userService"  class="com.mycompany.service.UserService"/>
<beans:bean id="myCustomUserDetailService" class="com.mycompany.service.MyCustomUserDetailService"/>
<beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
    <beans:property name="userPropertyToUse" value="salt"/>
</beans:bean>

<authentication-manager>
  <authentication-provider user-service-ref="myCustomUserDetailService">
    <password-encoder ref="bcryptEncoder">
      <salt-source ref="saltSource"/>
    </password-encoder>
  </authentication-provider>
</authentication-manager>

In this configuration, I indicate that the PasswordEncoder must use User.getSalt();

Problem : I get the following Error 500 :

Salt value must be null when used with crypto module PasswordEncoder.

After looking on stackoverflow, it seems that the salt must be null because BCryptPasswordEncoder uses its own SaltSource.

  1. Is there a way to use my SaltSource? OR
  2. Which reliable algorithm would allow my SaltSource?

Thanks.

Upvotes: 4

Views: 2570

Answers (1)

Eugene
Eugene

Reputation: 2701

Answer to first question:

BCryptPasswordEncoder has hardcoded salt source (Bcrypt.getsalt).
So it is not possible to force BCryptPasswordEncoder to use other salt source.
Nevertherless, you may try subclass it, and add custom salt property.

Upvotes: 4

Related Questions