Encrypt User Password Example in Java

When user signs up with our Mobile App we ask them to come up with a secure password and then we take that password and store it in database. We all know it is not secure to store user password as is because anyone who looks at the users database table will be able to see real users passwords. We need to somehow protect them from being easily read and for a long time we used MD5 to hash the password value to somehow protect it and not store as is. But MD5 is not a secure way anymore and there is a better way to do it.

The below code example will help you:

  • Generate Salt value
  • Use password-based encryption to encrypt user password
  • Encode secure user password into Base64

Once you have a secure value of user password encoded in Base64 you can save it in your database together with salt value. The Salt value and the Base64 encoded value of password will need to be stored together because you will need both of these values to be able to validate if provided(unencrypted user password) matches the one which is encrypted and stored in your 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

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 this code it generated:

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!

Happy coding!