Storing password in java

How to Securely Store Passwords in Java

One of the common requirements in Java web application is the secure storage of user passwords. You should never store user passwords in plain text. Passwords must be stored in such a way that there should be no way of getting the original password from the stored representation. Cryptographic one way hash functions are perfect for this purpose. Same hash is generated for the same password, but the original password cannot retrieved from the hash alone.

There are a number of common hash functions in use such as MD5, SHA1, SHA256 etc. I have also seen many implementations using them directly for password storage. However these are not suitable for password hashes due to a number of reasons — the algorithms such as SHA256 are too fast and hence brute forcing the hash is easy. Using MD5 hash without a salt is almost as bad as storing plain text passwords!

There are a number of hash functions specifically designed for storing hashed passwords. These include PBKDF2, bcrypt, scrypt etc. PBKDF2 is an excellent hash algorithm for password hashing and is one of the NIST recommended algorithms.

Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks. Secrets SHALL be hashed with a salt value using an approved hash function such as PBKDF2 as described in [SP 800-132]. The salt value SHALL be a 32-bit or longer random value generated by an approved random bit generator and stored along with the hash result. At least 10,000 iterations of the hash function SHOULD be performed. A keyed hash function (e.g., HMAC [FIPS198-1]), with the key stored separately from the hashed authenticators (e.g., in a hardware security module) SHOULD be used to further resist dictionary attacks against the stored hashed authenticators.

One of the issues with hash functions is that they are susceptible to rainbow table attack. This attack can be prevented by using a salt text (a random text) along with each password before hashing it. This ensures that even when two different users use the same password, the hash values stored are different.

Читайте также:  Ipynb to html online

The following Java program demonstrates the use of PBKDF2 hash algorithm with salt text for storing passwords. It uses NIST recommended specification. The following example will run on Java SE 8 or above. If you want to use it Java 7 or below replace the Base64 class with Apache commons codec Base64 class.

Please note that the salt stored for the user must be changed when password is updated.

import java.security.SecureRandom; import java.security.spec.KeySpec; import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class SecurePasswordStorageDemo < // Simulates database of users! private MapuserDatabase = new HashMap(); public static void main(String[] args) throws Exception < SecurePasswordStorageDemo passManager = new SecurePasswordStorageDemo(); String userName = "admin"; String password = "password"; passManager.signUp(userName, password); Scanner scanner = new Scanner(System.in); System.out.println("Please enter username:"); String inputUser = scanner.nextLine(); System.out.println("Please enter password:"); String inputPass = scanner.nextLine(); boolean status = passManager.authenticateUser(inputUser, inputPass); if (status) < System.out.println("Logged in!"); >else < System.out.println("Sorry, wrong username/password"); >scanner.close(); > private boolean authenticateUser(String inputUser, String inputPass) throws Exception < UserInfo user = userDatabase.get(inputUser); if (user == null) < return false; >else < String salt = user.userSalt; String calculatedHash = getEncryptedPassword(inputPass, salt); if (calculatedHash.equals(user.userEncryptedPassword)) < return true; >else < return false; >> > private void signUp(String userName, String password) throws Exception < String salt = getNewSalt(); String encryptedPassword = getEncryptedPassword(password, salt); UserInfo user = new UserInfo(); user.userEncryptedPassword = encryptedPassword; user.userName = userName; user.userSalt = salt; saveUser(user); >// Get a encrypted password using PBKDF2 hash algorithm public String getEncryptedPassword(String password, String salt) throws Exception < String algorithm = "PBKDF2WithHmacSHA1"; int derivedKeyLength = 160; // for SHA1 int iterations = 20000; // NIST specifies 10000 byte[] saltBytes = Base64.getDecoder().decode(salt); KeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, iterations, derivedKeyLength); SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm); byte[] encBytes = f.generateSecret(spec).getEncoded(); return Base64.getEncoder().encodeToString(encBytes); >// Returns base64 encoded salt public String getNewSalt() throws Exception < // Don't use Random! SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); // NIST recommends minimum 4 bytes. We use 8. byte[] salt = new byte[8]; random.nextBytes(salt); return Base64.getEncoder().encodeToString(salt); >private void saveUser(UserInfo user) < userDatabase.put(user.userName, user); >> // Each user has a unique salt // This salt must be recomputed during password change! class UserInfo

Читайте также:  Datetime strftime python 3 примеры

Источник

Storing Hashed Password to Database in Java(Using Bcrypt)

Storing passwords in plain text in databse is vulnerable to security. This article is about storing hashed password to databse in java. Doing so it becomes impossible for even BDAs to extract the real passwords. There are many hashing algorithms such as MD5 , SHA-1 , SHA-2 etc to hash a password but adding a salt to the password provides extra security. In this article we will be using jBCrypt , which internally generates a random salt while encoding passwords, to encode our plain text passwords and store in DB.

In this article, we will be using spring MVC and hibernate just to get rid of some configurations to connect with DB. The main focus here will be to use jBCrypt to encode the plain text passwords and save to DB and again how can we match the hashed password with the plain text password. Here we will be creating a simple app that encryptes password before storing user details in the DB.

What is Bcrypt Encoding

As per wiki, bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher. Bcrypt uses adaptive hash algorithm to store password.BCrypt internally generates a random salt while encoding passwords and hence it is obvious to get different encoded results for the same string.But one common thing is that everytime it generates a String of length 60.

You can also take a look into this Online Bcrypt Tool to know how bcrypt works.

 Other Interesting Posts AES Encryption and Decryption in Java Spring Data JPA Example Spring Boot Hibernate 5 Example Spring Hibernate Integration Example Spring Boot Security Bcrypt Password Encoding Random Password Generator in Java Spring MVC PDF and Excel View Example Spring MVC Content Negotiating Example Spring Boot Multiple DB Example 

Defining maven Dependencies

Following is the maven dependency required to get started using Bcrypt.

<dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.3m</version> </dependency>

Bcrypt Implementation to Encrypt Password

Bcrypt library provides ready made implementation to hash plain text password. The method hashpw() requires plain text password and random salt to hash a plain text password. Following is the implementation.The save() method defined in the UserServiceImpl.java internally calls following method to encrypt the password before saving it to the DB.

private String hashPassword(String plainTextPassword)< return BCrypt.hashpw(plainTextPassword, BCrypt.gensalt()); >

Matching Encrypted and Plain Text Password in Bcrypt

Following is the implementation that actually matches the plain text and encrypted password.

private void checkPass(String plainPassword, String hashedPassword) < if (BCrypt.checkpw(plainPassword, hashedPassword)) System.out.println("The password matches."); else System.out.println("The password does not match."); >

Testing the Application

Here first we will save a user in the db. The service implementation will encrypt the password before saving to DB. Then we will fetch the same user from DB and try to match the enccrypted password with the plain text password and display the result.

@WebAppConfiguration @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = < TestBeanConfig.class >) public class UserControllerTest < @Autowired private UserController userController; private String password = "password"; @Test public void validateUser_Test_Positive() < User user = new User(); user.setEmail("test@test.com"); user.setName("test"); user.setPassword(password); userController.save(user); ResponseEntity result = userController.getUser(user.getId()); assertNotNull(result.getBody()); checkPass(password, user.getPassword()); assertEquals(result.getStatusCode(), HttpStatus.OK); > private void checkPass(String plainPassword, String hashedPassword) < if (BCrypt.checkpw(plainPassword, hashedPassword)) System.out.println("The password matches."); else System.out.println("The password does not match."); > >

Following is the entry created in databse after executing above test.

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Источник

Storing Hashed Password to Database in Java(Using Bcrypt)

Storing passwords in plain text in databse is vulnerable to security. This article is about storing hashed password to databse in java. Doing so it becomes impossible for even BDAs to extract the real passwords. There are many hashing algorithms such as MD5 , SHA-1 , SHA-2 etc to hash a password but adding a salt to the password provides extra security. In this article we will be using jBCrypt , which internally generates a random salt while encoding passwords, to encode our plain text passwords and store in DB.

In this article, we will be using spring MVC and hibernate just to get rid of some configurations to connect with DB. The main focus here will be to use jBCrypt to encode the plain text passwords and save to DB and again how can we match the hashed password with the plain text password. Here we will be creating a simple app that encryptes password before storing user details in the DB.

What is Bcrypt Encoding

As per wiki, bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher. Bcrypt uses adaptive hash algorithm to store password.BCrypt internally generates a random salt while encoding passwords and hence it is obvious to get different encoded results for the same string.But one common thing is that everytime it generates a String of length 60.

You can also take a look into this Online Bcrypt Tool to know how bcrypt works.

 Other Interesting Posts AES Encryption and Decryption in Java Spring Data JPA Example Spring Boot Hibernate 5 Example Spring Hibernate Integration Example Spring Boot Security Bcrypt Password Encoding Random Password Generator in Java Spring MVC PDF and Excel View Example Spring MVC Content Negotiating Example Spring Boot Multiple DB Example 

Defining maven Dependencies

Following is the maven dependency required to get started using Bcrypt.

<dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.3m</version> </dependency>

Bcrypt Implementation to Encrypt Password

Bcrypt library provides ready made implementation to hash plain text password. The method hashpw() requires plain text password and random salt to hash a plain text password. Following is the implementation.The save() method defined in the UserServiceImpl.java internally calls following method to encrypt the password before saving it to the DB.

private String hashPassword(String plainTextPassword)< return BCrypt.hashpw(plainTextPassword, BCrypt.gensalt()); >

Matching Encrypted and Plain Text Password in Bcrypt

Following is the implementation that actually matches the plain text and encrypted password.

private void checkPass(String plainPassword, String hashedPassword) < if (BCrypt.checkpw(plainPassword, hashedPassword)) System.out.println("The password matches."); else System.out.println("The password does not match."); >

Testing the Application

Here first we will save a user in the db. The service implementation will encrypt the password before saving to DB. Then we will fetch the same user from DB and try to match the enccrypted password with the plain text password and display the result.

@WebAppConfiguration @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = < TestBeanConfig.class >) public class UserControllerTest < @Autowired private UserController userController; private String password = "password"; @Test public void validateUser_Test_Positive() < User user = new User(); user.setEmail("test@test.com"); user.setName("test"); user.setPassword(password); userController.save(user); ResponseEntity result = userController.getUser(user.getId()); assertNotNull(result.getBody()); checkPass(password, user.getPassword()); assertEquals(result.getStatusCode(), HttpStatus.OK); > private void checkPass(String plainPassword, String hashedPassword) < if (BCrypt.checkpw(plainPassword, hashedPassword)) System.out.println("The password matches."); else System.out.println("The password does not match."); > >

Following is the entry created in databse after executing above test.

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Источник

Оцените статью