2

So far my application is hashing user passwords using simple MD5 algorithm now we have introduced Spring Security in the application and would prefer using BCrypt instead. My problem how can I migrate old passwords to new Algorithm.

  1. Can I give multiple password encoders to Spring Security so that they can be used in turn ?
  2. After successful login how to change the password since password is transmitted using SHA1 algorithm ?

For problem 1, I believe using CustomAuthenticationProvider may work but I am totally confused about how to use that in our system. Below is my configureGlobal function from SecurityConfig class

@Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .passwordEncoder(passwordEncoder)
                    .usersByUsernameQuery("SELECT uname AS username, upwd AS password, true AS enabled FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?")
                    .authoritiesByUsernameQuery("SELECT uname AS username, 'Default' AS role FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?");
        }

I have not used UserDetailsService in my application and only above queries are supplied. I have used CustomUsernamePasswordAutheticationFilter and CustomPasswordEncoder if that can be useful in this problem.

Thanks,

Amit
  • 13,134
  • 17
  • 77
  • 148
  • MD5 is a one way Hashing Algorithm which cannot be decrypted (Even though most possible MD5 Hashes's plaintext passwords are found in online, by theoritically it cannot be decrypted). One possible solution is to change the password stored in DB from MD5 to Bcrypt using the plaintext password provided by user during login (Ofcourse only after successful login). – The Coder Jul 08 '15 at 07:43
  • You should be able to subclass `BCryptPasswordEncoder`, override the `matches` method to first let `BCryptPasswordEncoder` match and if a match is unsuccessful, try an MD5 match with your existing code. Rather than trying to re-hash existing passwords, it may be better to advise users to change their passwords once you have shifted fully to BCrypt. If you have robust `Forgot Password` functionality, it may even be possible to not match against MD5 and let users choose new passwords (which will be encrypted with BCrypt anyway). – manish Jul 08 '15 at 07:52
  • @user1354678 Plain text passwords don't travel in network so at server side I have no idea what the password was :( even after successful login. – Amit Jul 08 '15 at 08:21
  • Could you elaborate on *password is transmitted using SHA1 algorithm* ? Normally when you store encoded password, you receive the clear text password (or something that you process as a clear text password), encode it and ensure the encoded forms match. So you should be able to rewrite a BCrypt encoded password after a successful login - implementation still being to define :-) – Serge Ballesta Jul 08 '15 at 08:25
  • @SergeBallesta I send the SHA1 encoded password to client and while checking against the value from DB I perform SHA1 on db password value (which is the MD5 encoded password). – Amit Jul 08 '15 at 08:44
  • @manish I think your comment could be one of the possible answers. Please paste it as answer. – Amit Jul 08 '15 at 08:44

1 Answers1

4

You should be able to subclass BCryptPasswordEncoder, override the matches method to first let BCryptPasswordEncoder try and find a match and if a match is unsuccessful, try an MD5 match with your existing code. This way, everyone who has a BCrypt hashed password and provides the correct value will get logged in fast (due to the built-in BCryptPasswordEncoder logic). Everyone who has an old MD5 hashed password and provides the correct value will also get logged in (due to your custom code), but will incur the additional penalty of having gone through a BCrypt match first. Everyone else will not be logged in but the login failure path will incur the additional penalty of the MD5 check.

Rather than trying to re-hash existing passwords, it may be better to advise users to change their passwords once you have shifted fully to BCrypt since then the newly selected passwords will automatically get hashed using BCrypt and you will save yourself the hassle of matching against an MD5 hash. Many companies have done this in the past so this may not be such a surprising move for the users.

If you have robust Forgot Password functionality, it may even be possible to not match against MD5 at all. You will simply let users logging in with an old MD5 hashed password fail and ask them to use the Forgot Password functionality to create a new one (which will be encrypted with BCrypt anyway).

manish
  • 19,695
  • 5
  • 67
  • 91