package org.superdev.coddy.user.utils;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;

public class SecurityUtils {

    private static final int SALT_SIZE = 32;
    private static final int KEY_LENGTH = 512;
    private static final int ITERATIONS = 1000;
    private static final String ALGORITHM = "PBKDF2WithHmacSHA512";

    private SecurityUtils() {

    }

    public static byte[] hash(char[] password, byte[] salt) {
        try {
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(SecurityUtils.ALGORITHM);
            PBEKeySpec spec = new PBEKeySpec(password, salt, SecurityUtils.ITERATIONS, SecurityUtils.KEY_LENGTH);
            SecretKey key = secretKeyFactory.generateSecret(spec);
            return key.getEncoded();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new SecurityException(e);
        }
    }

    public static byte[] generateSalt() {
        final Random r = new SecureRandom();
        byte[] salt = new byte[SecurityUtils.SALT_SIZE];
        r.nextBytes(salt);
        return salt;
    }

}

package org.superdev.coddy.user.utils;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;

public class SecurityUtils {

    private static final int SALT_SIZE = 32;
    private static final int KEY_LENGTH = 512;
    private static final int ITERATIONS = 1000;
    private static final String ALGORITHM = "PBKDF2WithHmacSHA512";

    private SecurityUtils() {

    }

    public static byte[] hash(char[] password, byte[] salt) {
        final PBEKeySpec spec = new PBEKeySpec(password, salt, SecurityUtils.ITERATIONS, SecurityUtils.KEY_LENGTH);

        try {
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(SecurityUtils.ALGORITHM);
            SecretKey key = secretKeyFactory.generateSecret(spec);
            return key.getEncoded();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new SecurityException(e);
        } finally {
            // erase the password in the char array in order to not retrieve it in the java memory
            spec.clearPassword();
        }
    }

    public static byte[] generateSalt() {
        final Random r = new SecureRandom();
        byte[] salt = new byte[SecurityUtils.SALT_SIZE];
        r.nextBytes(salt);
        return salt;
    }

    public static boolean isExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) {
        if (password == null) {
            return false;
        }
        final byte[] pwdHash = SecurityUtils.hash(password, salt);
        final int length = pwdHash.length;

        // erase the password in the char array in order to not retrieve it in the java memory
        Arrays.fill(password, Character.MIN_VALUE);

        if (length != expectedHash.length) {
            return false;
        }

        int i = 0;
        boolean result = true;

        while ((i < length) && result) {
            result = pwdHash[i] == expectedHash[i];
            i++;
        }

        return result;
    }

}

add utils security method to check the password