When a user signs up for our mobile app, we require them to create a secure password, which we then store in our database. However, we know that storing passwords as plain text is not secure, as it allows anyone who views the database to access users’ actual passwords. To protect these passwords from being easily read, we need to encrypt them. While we have used the MD5 algorithm in the past to hash passwords, this method is no longer considered secure, so we need to explore alternative encryption options.
The following code example will help you to:
- Generate a salt value
- Use password-based encryption to encrypt the user’s password
- Encode the encrypted password into Base64 format
Once you have an encoded, secure value of the user’s password in Base64, you can save it in the database along with the salt value. Both the salt value and the Base64-encoded password must be stored together, as they are required to validate if the unencrypted user-provided password matches the encrypted password stored in the database.
PasswordUtils Java class used to encrypt and verify user password.
package com.appsdeveloperblog.encryption; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; import java.util.Random; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class PasswordUtils { private static final Random RANDOM = new SecureRandom(); private static final String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static final int ITERATIONS = 10000; private static final int KEY_LENGTH = 256; public static String getSalt(int length) { StringBuilder returnValue = new StringBuilder(length); for (int i = 0; i < length; i++) { returnValue.append(ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length()))); } return new String(returnValue); } public static byte[] hash(char[] password, byte[] salt) { PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH); Arrays.fill(password, Character.MIN_VALUE); try { SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); return skf.generateSecret(spec).getEncoded(); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new AssertionError("Error while hashing a password: " + e.getMessage(), e); } finally { spec.clearPassword(); } } public static String generateSecurePassword(String password, String salt) { String returnValue = null; byte[] securePassword = hash(password.toCharArray(), salt.getBytes()); returnValue = Base64.getEncoder().encodeToString(securePassword); return returnValue; } public static boolean verifyUserPassword(String providedPassword, String securedPassword, String salt) { boolean returnValue = false; // Generate New secure password with the same salt String newSecurePassword = generateSecurePassword(providedPassword, salt); // Check if two passwords are equal returnValue = newSecurePassword.equalsIgnoreCase(securedPassword); return returnValue; } }
Protect User Password Code Example in Java
The below code example if encrypt user password and will generate a secure value that can be stored in a database.
package com.appsdeveloperblog.encryption; public class ProtectUserPassword { public static void main(String[] args) { String myPassword = "myPassword123"; // Generate Salt. The generated value can be stored in DB. String salt = PasswordUtils.getSalt(30); // Protect user's password. The generated value can be stored in DB. String mySecurePassword = PasswordUtils.generateSecurePassword(myPassword, salt); // Print out protected password System.out.println("My secure password = " + mySecurePassword); System.out.println("Salt value = " + salt); } }
When I ran the above code in my development environment it generated the following output:
Encrypted and Base64 encoded user password: HhaNvzTsVYwS/x/zbYXlLOE3ETMXQgllqrDaJY9PD/U=
Salt value:
EqdmPh53c9x33EygXpTpcoJvc4VXLK
I can store the above two values in my database and I will use them in the below code example to verify if provided user password is correct and matches my database record.
Validate User Password Code Example in Java
package com.appsdeveloperblog.encryption; public class VerifyProvidedPassword { public static void main(String[] args) { // User provided password to validate String providedPassword = "myPassword123"; // Encrypted and Base64 encoded password read from database String securePassword = "HhaNvzTsVYwS/x/zbYXlLOE3ETMXQgllqrDaJY9PD/U="; // Salt value stored in database String salt = "EqdmPh53c9x33EygXpTpcoJvc4VXLK"; boolean passwordMatch = PasswordUtils.verifyUserPassword(providedPassword, securePassword, salt); if(passwordMatch) { System.out.println("Provided user password " + providedPassword + " is correct."); } else { System.out.println("Provided password is incorrect"); } } }
I hope this little tutorial is helpful to you!
Also, check the below video courses on Java. Hopefully, you will also find one of them helpful.
Happy learning!