Which mean, even if your database is compromised and a malicious user get access to all the password, they will not be able to recover original password require to login into your system. This is a much safer approach than storing plain-text password into database. Though hashing minimize the risk of recovering original password, your system is still not full-proof. For example, if two user have same password then their encrypted password or hash value will be same. Which means, if someone have access to all passwords of your system they can still try a brute force attack where common passwords are encrypted using same hashing algorithm and looked up against the stored password. This hacking technique is also known as rainbow tables. Salting solve this problem by generating unique hashing value for each user even if they have the same password. In case of Salting, a randomly generated plain-text value is combine to the plain-text password and passed to hashing algorithm.
Since we are using a unique value for each user, the generated encrypted password will always be unique. Btw, the uniqueness of encrypted password also depends upon the salt value. A good salting algorithm generate unique salt values which eventually generate unique encrypted password. In general, many application uses user creation timestamp as salt value or a randomly generate value from a good algorithm. One more thing you need to remember is that you also need to store a salt value now. Sine user doesn't know about salt value, they will just enter password and you need to always use the same salt value to generate encrypted password which is then matched to stored password and if they match, spring security allows user to login. Since we cannot store plaintext salt due to the same security reason discussed above, we need to again use a hashing algorithm to generate encrypted form of salt but this time we need to use a two-way hashing algorithm e.g. Bcrypt because we also need to retrieve plain-text salt from encrypted value to again generate encrypted password for login process.
Some of the useful hashing algorithms are SHA and SHA-256 and Spring security supports both of them. Similarly Spring Security also support different hashing algorithm for salting e.g. bcrypt hashing function. Now that you have good understanding of password hashing and salting, let's see how to hash password using Spring Security. How to secure Passwords using Spring Security? Spring Security provides a PasswordEncoder class (org.springframework.security.authentication.encoding.PasswordEncoder) to secure password in Java web application. This is generally used when you save password into database and use Spring Security's JDBC authentication support. In this configuration we are using sha-256 algorithm for hashing but Spring security provide a couple of more implementation which can be specified using the hash attribute of tag. Encodes the password as plaintext, this is the default and hash value for this implementation is "plaintext". It uses MD5 one-way encoding algorithm for hashing. Hash value for this is "md5". This PasswordEncoder implementation uses the SHA one-way encoding algorithm.
It also support configurable level of encoding strength. For example to use SHA-256 you can pass 256 into its constructor. The hash value for ShaPasswordEncoder is "sha" and for SHA-256 its "sha-256". This is a version of ShaPasswordEncoder which supports LDAP SHA and LDAP SSHA (salted-SHA) encoding algorithms used in integration with LDAP authentication stores. Once you configure PasswordEncoder in Spring Security configuration, it will automatically use password hashing while verifying login credential or storing new user password into database. So far, we have not used salt. Password hashing and Salting in Spring Security. Spring Security 3.1 release provided a new cryptography module (spring-security-crypto) which is also part of spring-security-core module. This module contains another PasswordEncoder interface(org.springframework.security.crypto.password.PasswordEncoder) which uses a random salt while encoding passwords. This is the preferred method to secure password in spring security because of added security provided using salt. This interface contains two methods encode(CharSequence rawPassword) to encode plaintext password and matches(CharSequence rawPassword, String encodedPassword) to verify the encoded password obtained from storage matches the submitted raw password after it too is encoded.
|