2

I have a user table containing both MD5 (legacy stuff) and BCrypt password. I would like to migrate MD5 password to BCrypt, without bruteforce them. I thought about re-encrypt passwords on successful authentication.

However (so far in my investigation), I can only get clear password (from login page) if I disable erase-credentials in authentication-manager declaration. In this case, I have access to credentials information not only from my custom AuthenticationSuccessHandler, but from anywhere in my application as well (using SecurityContextHolder.getContext().getAuthentication() ).

Is there a way to access clear password on successful authentication only ? Or do you know a better way to re-encrypt passwords without asking for user manipulation (password change, etc.) ?

Thank you

ssssteffff
  • 964
  • 4
  • 16

1 Answers1

0

A solution is to create a password encoder that accepts both legacy MD5 hash and value from new, better (BCrypt) encoder, and migrates MD5 hash when finding one.

@Component
public class MigratingPasswordEncoder implements PasswordEncoder {

    @Autowired
    private org.springframework.security.crypto.password.PasswordEncoder passwordEncoder; // new encoder (BCrypt)

    @Autowired
    private Md5PasswordEncoder legacyEncoder;

    @Autowired
    private UserDao userDao; // where password hashes are stored

    public String encodePassword(String rawPass, Object salt) {
        return passwordEncoder.encode(rawPass);
    }

    public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
        if (legacyEncoder.isPasswordValid(encPass, rawPass, salt)) {
            // MD5 hash found here, save a new hash instead
            userDao.updatePassword(encPass, passwordEncoder.encode(rawPass));
            return true;
        }
        return passwordEncoder.matches(rawPass, encPass);
    }
}

Deprecation note: This uses the old PasswordEncoder interface in org.springframework.security.authentication.encoding package, but it is quite unavoidable since since Md5PasswordEncoder also uses that interface.

Credit: Inspired from the answer of Spring security 3.1.4 and ShaPasswordEncoder deprecation.

holmis83
  • 15,922
  • 5
  • 82
  • 83