How to Set BCrypt Password Encoding in Spring Boot Security?

banner

Understanding Password Encoder in Springboot:

In this blog I will help you understand the Bcrypt cryptography algorithm and how to use the decrypt password encoder in a spring boot project with spring security.

Using Bcrypt for password encoding in your Spring Boot project enhances security by protecting against rainbow table attacks. Java development company should consider integrating Bcrypt in their applications to ensure user passwords are securely stored and handled. With Spring Security, implementing Bcrypt is straightforward and provides robust protection for your users' data.

What is Bcrypt? It is a password hashing function based on BlowFish symmetric block cipher algorithm and crypt which your password hashing function in UNIX. Bcrypt is highly secure because a slat is used to protect against rainbow table attacks and it is an adaptive hashing function with the cryptographic chunk that can be increased when computer hardware gets faster that means the hashing function can be configured to run slower which also means it can slow down attacks.

BCrypt Algorithm:

Let's understand the Bcrypt algorithm with some pseudo-code. Suppose that we want to generate a hash value for a given password. So, the input of the algorithm is the cost of the chunks of the algorithm, salt and a given password and then it initializes the state by setting up an expensive key using a BlowFish algorithm for the cost, salt and password.

Then the ciphertext is chosen with the magic value(OrpheanBeholderScryDoubt) and then the ciphertext is encrypted repeatedly 64 times and finally, it returns the hash string, which is the concatenation of the cost, salt and ciphertext.

Bcrypt -> Methods Signature -> Bcrypt(cost, salt, password) States:- EKsBlowFishSetup(cost, salt, password) CipherText <- OrpheanBeholderScryDoubt) CipherText=EncryptECB(State, CipherText) Concat(coast, salt, cipherText) -> return the Result

That means for a given password the Bcrypt algorithm produced a hash string which is a result of encrypting the magic text here 64 times using BlowFish algorithm with the private key is a given password. It means the password itself is not encrypted hashed even it is used as a private key to hash this magic value 64 times.

Bcrypt(anyPlainpassword) = encrypted_Password;

It encrypts the special initial Bcrypt text 64 times using BlowFish with a private key and this private key is nothing but the given password.

Let us help you create a robust and secure application that protects your users' data.

Bcrypt Hashing Technique

Now let's read carefully here the format of the hash string produced by the Bcrypt. The prefix is a “version” and is followed by the dollar sign ($). The check strength of the algorithm dollar sign and the next 22 characters is SALT. And, the last 31 characters are the hashed value of the magic ciphertext.

bcrypt1

Here's an example of hash chunks produced by Bcrypt. As you can see the version number is dollar 2a and the chunk or the Cost is 10. These characters have a hash value of magic ciphertext and the versions can be dollar 2a/2b. The chunked or strength of the Cost of the algorithm is ranging from 4 to 31.

Encoded password=$2a$10$15NHFNWR1obB6Gw4hO5wmeJDJPt9iPYOObNUkuMEQ2R0mdrEWlE2i
Versions=$2a, $2b, $2y
SALT16 Bytes Base64 Encoded to 22 total number of Characters
Hash String24 Bytes Base64 Encoded to 31 total number of Characters
Cost or Strength = 4 to 31 & Total Length = 60 Chars

The higher the chunk or strength value, the more computational power it needs to generate the hash string and the size of the salt is 128 bit base64encoded to 22 characters. The size of the hash is 192 bits by 64 encoded to 31 characters.

So, the total length of the hash String produced by the Bcrypt is 60 characters. Therefore, when designing a column in the database make sure that the size of the data type of the column is equal to or greater than 60 characters.

How to implement Bcrypt Password Encoder in Spring Security

Let's understand how spring security supports Bcrypt to use the BCrypt password encoder in a Spring boot project. We need to import classes from this package (org.springframework.security.crypto.bcrypt) and the api class is BCrypt password encoder. We have to use this class to encode our password into a hash string and we also use this class to verify your password against an encoded value and the algorithm implementation class is BCrypt.

This class is used by the BCrypt password encoder class and for the versions of the BCrypt algorithm, spring-security defines an Enum BCryptVersion inside the BCryptPasswordEncoder class.

In spring-security, the default strength of the Bcrypt algorithm is 10. The salt is random, and the default version is dollar 2a.

Now I am going to explain to you some good examples with we BCrypt password encoder in the spring boot project. You see this a spring boot project, to use BCrypt password encoder, you need to have this spring security starter dependency available in the project POM file.

I have created a new test class here called as BCryptPass.class and here we can write a JUnit test to encode a very simple robust password. I have created a method to encode a password string and method name is encodePlainPassword(). In this method, we will encode a sample raw password string i.e. let’s say “Hello Password String”.

Encode your BCrypt passwords and ensure the security of your application. Contact us further!

So, then we have to create a new instance of the BCrypt password encoder class. As you can see there are several contractors for the BCryptPasswordEncoder(), so we have to choose the default no-argument constructor or we can use the constructor that allows us to define to specify the version or the strength here. I have used the no-argument constructor.

@RunWith(SpringJUnit4ClassRunner.class) public class validatorServiceTest extends FTBase{ @Autowired private ValidatorServiceImpl validatorService; @Test public void encodeEncryptUserPassword(){ String password = "Hello Password String"; ByCryptPasswordEncoder passwordEncoder = new ByCryptPasswordEncoder(); String testPasswordEncoded = passwordEncoder.ecode(password); System.printIn("encoded password = "+testPasswordEncoded); } }

As you know the strength is 10 and the version is a dollar 2a default and then we have to encode the password by calling the encode() method of the BCryptPasswordEncoder class. And then we bring the encoded password to the standard output. The encoding method is used to generate a hash hashed string value for a given password.

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class BCryptTest{ public static void main(String[] args) { //TOOO Auto generated method stub encodeEncryptUserPassword(); } public static void encodeEncryptUserPassword() { String password = "Hello Password String"; BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String testPasswordEncoded = passwordEncoder.encode(password); System.out.printIn("encoded password = "+ testPasswordEncoded); } }

If I run this test method then you can see the hash value here you can see the version number dollar 2a, strength 10 and followed by the salt and then the actual hash value so. It's very quick to write with the default strength 10 here.

But when using a password encoder code in spring security, you can use the method matches() to verify your password against an encoded value. Then this match method returns the Boolean value if a match is true. Then I have used assert statements to verify if the match value returned is true or not.

@RunWith(SpringJUnit4ClassRunner.class) public class ValidatorServiceTest extends FTBase{ @Autowired private ValidatorServiceImp1 validatorService; @Test public void encodeEncryptUserPassword(){ String password = "Hello_Passowrd_String"; String testPasswordEncoded = passwordEncoder.ecode(password); System.out.printIn(Encoded Password ="+ testPasswordEncoded); boolen matched = passwordEncoder.matches("Hello_Passowrd_String",testPasswordEncoded); assertTrwt(matched); } @Test public void testEncrypted() { byte[] decodeAccessKeyPin = base64.getEncoder{}.decode("Passwordencode"); String decodeString = new String(DecodeAccessKeyPin); String decrypter = ValidatorService.decrypter(decoeString); assertEquals("Session:1234".decrypter); } }
Don't let security breaches hold you back! Reach out to us to learn more about our expert solutions for Spring Boot Security.

Note that the salt used by the Bcrypt algorithm is random. So, even with the same password if you run this test method again, you will see the value of the hash string will be different. Now I am going to modify the code to create a new instance of Bcrypt password encoder class with a specified version and strength number. This is really very interesting.

So, here I will be using use this constructor which accepts version $2b and strength is 7. So, it will generate the hashed string like below:

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.BCryptVersion; public class BCryptTest { public static void main(String[] args) { //TODO Auto Generated encodeEncryptUserPassword(); } public static void encodeEncryptUserPassword(){ String password = "Hello Password String"; BCryptPasswordEncoder passwordEncoder = new BycryptPasswordEncoder(BCryptVers); String testPasswordEncoded = passwordEncoder.encode(password); System.out.printIn("Encoded Password ="+ testPasswordEncoded); } }

Example of Bcrypt Password encoder in the DAO layer

We have already implemented spring security using spring boot in above example. Let's say you can be able to login using user name and password which is being fetched from Database. To achieve that we can use Authentication Provider Bean where we have to create a DAOAuthenticationProvider class instance.

Then we can assign customer service objects. But the main thing is to notice that here we have used the password encoder. Here we can specify the Bcrypt password encoder.

Dependency in Pom file:

<dependency> <groupId> org.springframework.boot</<groupId> > <artifactId>spring-boot-starter-security</artifactId> <version>2.4.4</version> </dependency> @Configuration @EnableWebSecurity @EnableAsync @EnableConfigurationProperties public class DeviceManagementConfig { @Autowired private DeviceManagementService service; @learn public AuthenticationProvider authProvider() { DeviceAuthenticatorProvider authprovider = new DeviceAuthenticatorProvider(); authProvider.setUserDetailService(service); authProvider.setPasswordEncoder(new BCryptPasswordEncoder()); return authProvider; } }

It is not recommended to use your password as plain text. If anyone can hack the database of your Java Web Apps, they will be seeing all your user passwords. At least your user details should be secured. For projects where you Outsource Java development, it's crucial to implement best practices for security. In a Spring Boot project, you don't have to add any extra library for using Bcrypt as it's already included by default. Please refer to the code below for implementation.

Are you struggling with Spring Boot Security? Our experts have got you covered! contact us mow!

Spring JDBC DataSource authentication using Bcrypt

I am using it here for enabling the JDBC authentication. For using the JDBC authentication we need to configure datasoruce instance first and for that, I have autowired it. Then I have created a bean of type BCryptPasswordEncoder.

Then you have to specify this encoder in the JDBC authentication so that spring security will know that the password that it is going to fetch from the database will be in the Bcrypt encoded format. Accordingly, it will have to handle this encoded password for authentication. Please refer to the below code snippet.

@Configuration @EnableSyncget @EnableSyncgetProperty public class DeviceManagementConfig { private final logger = LoggerFactory.getLogger(DeviceManagementConfig.class) @Autowired DataSource datsource; @learn public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Autowired public void configureAuthentication(Authenticator auth) Throws Excaption { auth.jdbcauthentication.datasource(DataSource).passwordEncoder(passwordEncoder()); } }

The above code takes care of the Bcrypt encoding during the login, however, during saving the password into a database, we have to save it in an encrypted format so that it gets securely stored in DB.

Now what I will do is, I am going to autowire the password Encode class and using this I am going to first encrypt the password that we get from customer and then this will be passed to the User object in our code. This is how encryption and encoding can be done.

Please refer to the above code where the password that we are receiving from the user we are encrypting this and then storing it into a database.

@Autowired private BCryptPasswordEncoder passwordEncoder; @RequestMapping(value="/user/register", method = RequestMethod.POST) public ModelAndView processRegistrationRequest(@ModelAttribute("customer") CustomerRegistration reg) { List<GrantedAuthority> auth = new ArrayList<>(); auth.add(new SimpleGrantedAuthority(reg.getAuthorities().getId(0).getAuthority())); // Here authority is of type "ROLE_ADMIN" String testPasswordEncoded = passwordEncoder.encode(reg.getCustomerPssword()); Customer customer = new Customer(reg.getCustomerUsername(), testPasswordEncoded, auth ); createNewCustomer(customer); //This calls the JDBC manager to save the customer details in DB return new ModelAndView("redirect:/home"); // Post successfully Login, redirects to the home page nothing but the welcome page }

Here in the above example, you can see that I have a Rest endpoint for Customer registration API and here I am accepting the customer details as a payload from the user including the plain password.

Before storing the password to a Customer object, first I am encoding the password using Bcrypt password encoder and then passing the encoded password to the Customer Object which is then passed to the DAO layer for storing it in database.

During the authentication, the same password is retrieved from the database and then it is decrypted and then verified against the customer’s password. Once it matches with the customer password then login is success otherwise an exception is thrown from the code as “Invalid username or Password”.

FAQs:

Subject: Implementing password encryption and encoding in Java Spring Boot Security using Bcrypt

It is a password hashing function based on BlowFish symmetric block cipher algorithm and crypt which your password hashing function in Unix. Bcrypt is highly secure because a slat is used to protect against rainbow table attacks.

For a given password the Bcrypt algorithm produced a hash string which is a result of encrypting the magic text here 64 times using BlowFish algorithm with the private key is a given password. It means the password itself is not encrypted hashed even it is used as a private key to hash this magic value 64 times

Firstly, need to include the spring security dependency in the pom file and then automatically spring security brings all the required packages of BCrypt password encoder. For more details please read the complete blog.

There are multiple constructors including the default constructor as well. Some constructor takes one parameter with the version and other with both version and strength etc.

The entire code is given in this blog. You have to autowire the required classes and then use them with Bcrypt encoder for password encoding.

Empower your Business with Team Aegis, CONNECT NOW!
captcha

Scale your Business with our Software Services Now!
Related article

On account of being at the cusp of API economy, Spring Boot and Jersey have been a boon to all developers.

Enterprise software solutions are not new to the corporate scene any longer; in fact, it seems like now everything – from the simplest to the most complex task - runs on a computer.

Recently updated over the last few months, Spring Initializr is an open-source, web-based tool that allows you to quickly create complex software programs within Spring Boot programs.

DMCA Logo do not copy