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;
    }

}

@@ -264,32 +264,57 @@
 ySpecException;%0A
+import java.util.Arrays;%0A
 import java.util
@@ -322,16 +322,16 @@
 Random;%0A
-
 %0Apublic 
@@ -658,24 +658,141 @@
 e%5B%5D salt) %7B%0A
+        final PBEKeySpec spec = new PBEKeySpec(password, salt, SecurityUtils.ITERATIONS, SecurityUtils.KEY_LENGTH);%0A%0A
         try 
@@ -900,122 +900,8 @@
 M);%0A
-            PBEKeySpec spec = new PBEKeySpec(password, salt, SecurityUtils.ITERATIONS, SecurityUtils.KEY_LENGTH);%0A
     
@@ -1117,16 +1117,169 @@
 ion(e);%0A
+        %7D finally %7B%0A            // erase the password in the char array in order to not retrieve it in the java memory%0A            spec.clearPassword();%0A
         
@@ -1458,16 +1458,16 @@
 (salt);%0A
-
         
@@ -1486,10 +1486,719 @@
 %0A    %7D%0A%0A
+    public static boolean isExpectedPassword(char%5B%5D password, byte%5B%5D salt, byte%5B%5D expectedHash) %7B%0A        if (password == null) %7B%0A            return false;%0A        %7D%0A        final byte%5B%5D pwdHash = SecurityUtils.hash(password, salt);%0A        final int length = pwdHash.length;%0A%0A        // erase the password in the char array in order to not retrieve it in the java memory%0A        Arrays.fill(password, Character.MIN_VALUE);%0A%0A        if (length != expectedHash.length) %7B%0A            return false;%0A        %7D%0A%0A        int i = 0;%0A        boolean result = true;%0A%0A        while ((i %3C length) && result) %7B%0A            result = pwdHash%5Bi%5D == expectedHash%5Bi%5D;%0A            i++;%0A        %7D%0A%0A        return result;%0A    %7D%0A%0A
 %7D%0A

add utils security method to check the password