Hello guys, if you are wondering whether Spring Security provides password hashing or not and wondering how to use it in your project then you have come to the right place. First, Yes, Spring Security provides out-of-the-box support for password hashing and salting, but before going into the details of how to use that, let's first understand what is password hashing and salting and why do you need that in a secure web application. One of the common requirement of a secure application is that password is never stored in the plain text. It doesn't matter if you are storing password in a database or a flat file they must be stored in encrypted form. The process to encrypt password for storing is known as hashing.
A plaintext password is passed to an algorithm known as hash function, which generate a hash value, an encrypted form of your password which is then stored into database. The most important thing about hashing algorithms is that converting plaintext password to encrypted is easy but converting hash value to original password is extremely difficult.
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. If you are not using salting then you can configure password encoder in Spring Security 3.1 by using <password-encoder> tag with the <authentication-provider> element as shown below:
<authentication-manager>
<authentication-provider user-service="myJDBCUserSerivce">
<password-encoder hash="sha-256">
<authentication-provider>
</authentication-manager>
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 <password-encoder> tag.
Here is a list of some of the common, out-of-the-box implementation class which you can use with password encoder:
1. PlaintextPasswordEncoder
Encodes the password as plaintext, this is the default and hash value for this implementation is "plaintext".
2. Md5PassowrdEncoderPassword
It uses MD5 one-way encoding algorithm for hashing. Hash value for this is "md5".
3. ShaPasswordEncoder
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".
4. LdapShaPasswordEncoder
This is a version of ShaPasswordEncoder which supports LDAP SHA and LDAP SSHA (salted-SHA) encoding algorithms used in integration with LDAP authentication stores. The hash value for this is is {sha} and {ssha}.
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. Btw, if you have to encrypt password manually, you can use following snippet:
ShaPasswordEncoder encoder = new ShaPasswordEncoder(256);
String hashedPassword = encoder.encodePassword(password, null);
So far, we have not used salt. let's see how we can use salting to further secure our web application in next section.
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.
Spring Security provide a couple of out-of-the-box implementation for this interface too which you can use directly in your project.
Here are some of the common implementations:
1. BCryptPasswordEncoder
Implementation of PasswordEncoder that uses the BCrypt strong hashing function. This is the preferred implementation . It supports salt and the ability to become slower to perform over time as technology improves. THis greatly helps protect against brute-force search attacks.
2. StandardPasswordEncoder
This implementation uses SHA-256 algorithm with multiple iteration and a random salt value.
3. SCryptPasswordEncoder.
Implementation of PasswordEncoder that uses the SCrypt hashing function. Clients can optionally supply a cpu cost parameter, a memory cost parameter and a parallelization parameter.
Important points
1) Hashing is a technique to encrypt password such that encrypt is easy but decrypting is very difficult. So that brute force attack on decrypting password would not succeed.
2) Some of the useful one-way hashing algorithms are SHA, SHA-256, and MD5.
That's all about password hashing and salting and Spring Security's support for them. As I said, Spring Security provides out-of-the-box support for hashing password and salting. You just need to include certain tags in your security configuration. One more thing I would like to remind you about is storing password in config file.
You should never ever store plain-text file in your script, code, or config file as these are hosted on Github or any other repository. Most of the organization have rules to prevent this from happening but this is also a best practice to follow and as a senior developer one should know about it.
Other Spring Security Articles and Resources you may like:
- 15 Spring Boot Interview Questions with Answers (questions)
- Top 5 Spring Boot Features Java developer should know (features)
- 10 Free Courses to learn Spring Boot for Beginners (free courses)
- 21+ Spring MVC Interview Questions for Java developers (Questions)
- Top 5 Courses to learn Microservices in Java (courses)
- How to Crack Spring Certification for Java developers (certification)
- 10 Advanced Spring Boot Courses for Java developers (courses)
- How to get a ServletContext object in the Spring controller? (example)
- Top 5 Courses to learn Spring Boot in-depth (courses)
- How to change the port of tomcat in Spring boot (tutorial)
- Top 5 Courses to learn Spring in depth (courses)
- Official Spring Security Documentation (docs)
- Top 5 Books to learn Spring Boot and Spring Cloud (books)
- What is the default bean scope in the Spring MVC framework? (answer)
- Top 5 Courses to learn Spring Cloud for Java developers (courses)
- 5 Best Resources for Spring Certification (resources)
Thanks for reading this article so far. If you have any questions or doubt about securing password with spring security, salting or hashing then feel free to ask in comments.
No comments:
Post a Comment