@@ -0,0 +1,1758 @@
+package com.xdrop.passlock.crypto;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport javax.crypto.SecretKey;%0Aimport javax.crypto.SecretKeyFactory;%0Aimport javax.crypto.spec.PBEKeySpec;%0Aimport javax.crypto.spec.SecretKeySpec;%0Aimport java.security.NoSuchAlgorithmException;%0Aimport java.security.SecureRandom;%0Aimport java.security.spec.InvalidKeySpecException;%0A%0Apublic class KeyDerivation %7B%0A%0A%0A    private static final Logger LOG = LoggerFactory.getLogger(KeyDerivation.class);%0A%0A    public static final String PBKDF2_ALGORITHM = %22PBKDF2WithHmacSHA256%22;%0A%0A    /* The size in bytes of the salt and the hash */%0A    private static final int SALT_BYTES = 8;%0A    private static final int KEY_BYTES = 128;%0A    private static final int ITERATIONS = 3000;%0A%0A%0A%0A    private static byte%5B%5D generateSalt(int bytes) %7B%0A%0A        // Generate a random salt%0A        SecureRandom random = new SecureRandom();%0A%0A        // Serve the bytes in a fresh array%0A        byte%5B%5D salt = new byte%5Bbytes%5D;%0A        random.nextBytes(salt);%0A%0A        return salt;%0A    %7D%0A%0A%0A    private static PBEKeySpec deriveKeySpec(char%5B%5D password, byte%5B%5D salt)%7B%0A        return new PBEKeySpec(password, salt, ITERATIONS, KEY_BYTES);%0A    %7D%0A%0A    public static SecretKey generateAESSecret(char%5B%5D password, byte%5B%5D salt)%7B%0A%0A        try %7B%0A%0A            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);%0A            PBEKeySpec keySpec = deriveKeySpec(password, salt);%0A            SecretKey tmp = secretKeyFactory.generateSecret(keySpec);%0A%0A            return new SecretKeySpec(tmp.getEncoded(),%22AES%22);%0A%0A        %7D catch (NoSuchAlgorithmException %7C InvalidKeySpecException e) %7B%0A            LOG.info(%22Failed to generate AES secret%22, e);%0A            return null;%0A        %7D%0A    %7D%0A%0A%0A%7D%0A

Add key derivation class for PBKDF