Password encoding and decoding using Spring Security, Spring Boot and MongoDB
First read Steven Carlson´s answer about password hashing.
The good thing is that Spring Security will do this for you. Spring Security 3.2 introduced the new org.springframework.security.crypto.password.PasswordEncoder
interface and some implementations: BCryptPasswordEncoder
, StandardPasswordEncoder
(and NoOpPasswordEncoder
).
Important: Do not confuse org.springframework.security.
crypto.password
.PasswordEncoder
with the old deprecated org.springframework.security.
authentication.encoding
.PasswordEncoder
The interface (and therefore the implementations) has the two methods you need:
public String encode(CharSequence rawPassword)
public boolean matches(CharSequence rawPassword, String encodedPassword)
I recommend to use org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
.
The BCryptPasswordEncoder
(in contrast to the StandardPasswordEncoder
) use an salt that is different for each password (but not global like the one from StandardPasswordEncoder
). When you encode a raw password (public String encode(CharSequence rawPassword)
) then the returned encoded password is not just the encoded password, it also contains some meta information about the used hash-algorithm, the used salt and of course the encoded password.
You should not be "encrypting" the password at all. I know this sounds counter-intuitive. But there is zero reason your system should need to decrypt the password. To do so would open your database to a hacker, because if you store your decryption password in your codes/server a hacker can steal that information.
The correct process is to hash
the password. A hash is a one-way (cannot be decypted back to the original text) process. The current standard would be to use SHA256 to hash your password. Here is a basic flow-chart:
- Take user submitted password. Example password "mypass" would hash out to
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
- Store this hash (
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
) in your database.
When a user logs in you take the password he just submitted and hash it. If he enters the same password it will hash out to the same value in your database.
When a user goes to change passwords you hash the "enter your old password" to verify the old password still matches, if it does you hash the "enter your new password" and save it.
One thing I did not mention in my example is salt
. This is something you must use in your system as it protects your data from rainbow table
exploits. But that is for another discussion.
Hope this helps :)