158 lines
4.7 KiB
Java
158 lines
4.7 KiB
Java
package database;
|
|
|
|
import java.util.Base64;
|
|
import java.util.Random;
|
|
|
|
import javax.crypto.*;
|
|
import javax.crypto.spec.*;
|
|
import java.security.*;
|
|
import java.security.spec.*;
|
|
|
|
class SQLiteEncryption {
|
|
|
|
private static final Random RANDOM = new SecureRandom();
|
|
private static final int ITERATIONS = 10000;
|
|
private static final int KEY_LENGTH = 256;
|
|
protected static final String encryptAlgorithm = "AES/CBC/PKCS5Padding";
|
|
|
|
/**
|
|
* Return a 24 bytes salt.
|
|
*
|
|
* @return The salt in a byte array.
|
|
*/
|
|
protected static byte[] getNextSalt() {
|
|
byte[] salt = new byte[24];
|
|
RANDOM.nextBytes(salt);
|
|
return salt;
|
|
}
|
|
|
|
/**
|
|
* Return the hash of the given password with the given salt.
|
|
*
|
|
* @param password
|
|
* @param salt
|
|
* @return The hash in a byte array.
|
|
*/
|
|
protected static byte[] hash(char[] password, byte[] salt) {
|
|
return SQLiteEncryption.getKey(password, salt).getEncoded();
|
|
}
|
|
|
|
/**
|
|
* Return a secret key generated with the given password and salt.
|
|
*
|
|
* @param password
|
|
* @param salt
|
|
* @return The secret key.
|
|
*/
|
|
protected static SecretKey getKey(char[] password, byte[] salt) {
|
|
PBEKeySpec saltpwd = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);
|
|
|
|
try {
|
|
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
|
SecretKey tmp = skf.generateSecret(saltpwd);
|
|
SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
|
|
return key;
|
|
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
|
e.printStackTrace();
|
|
} finally {
|
|
saltpwd.clearPassword();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return a 16 bytes Initialization vector.
|
|
*
|
|
* @return The Initialization vector.
|
|
*/
|
|
protected static IvParameterSpec generateIv() {
|
|
byte[] iv = new byte[16];
|
|
RANDOM.nextBytes(iv);
|
|
return new IvParameterSpec(iv);
|
|
}
|
|
|
|
/**
|
|
* Encrypt the given input (byte array) with the given algorithm, secretKey and
|
|
* initialization vector.
|
|
*
|
|
*
|
|
* @param algorithm
|
|
* @param input
|
|
* @param key
|
|
* @param iv
|
|
* @return The encrypted input in a byte array.
|
|
*
|
|
* @throws NoSuchAlgorithmException
|
|
* @throws NoSuchPaddingException
|
|
* @throws InvalidKeyException
|
|
* @throws InvalidAlgorithmParameterException
|
|
* @throws IllegalBlockSizeException
|
|
* @throws BadPaddingException
|
|
*/
|
|
protected static byte[] encrypt(String algorithm, byte[] input, SecretKey key, IvParameterSpec iv)
|
|
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
|
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
|
|
Cipher cipher = Cipher.getInstance(algorithm);
|
|
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
|
byte[] cipherText = cipher.doFinal(input);
|
|
return Base64.getEncoder().encode(cipherText);
|
|
}
|
|
|
|
/**
|
|
* Decrypt the given input (byte array) with the given algorithm, secretKey and
|
|
* initialization vector.
|
|
*
|
|
* @param algorithm
|
|
* @param input
|
|
* @param key
|
|
* @param iv
|
|
* @return The decrypted input in a byte array.
|
|
*
|
|
* @throws NoSuchAlgorithmException
|
|
* @throws NoSuchPaddingException
|
|
* @throws InvalidKeyException
|
|
* @throws InvalidAlgorithmParameterException
|
|
* @throws IllegalBlockSizeException
|
|
* @throws BadPaddingException
|
|
*/
|
|
protected static byte[] decryptByte(String algorithm, byte[] input, SecretKey key, IvParameterSpec iv)
|
|
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
|
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
|
|
Cipher cipher = Cipher.getInstance(algorithm);
|
|
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
|
byte[] plainText = cipher.doFinal(Base64.getDecoder().decode(input));
|
|
return plainText;
|
|
}
|
|
|
|
/**
|
|
* Decrypt the given input (byte array) with the given algorithm, secretKey and
|
|
* initialization vector.
|
|
*
|
|
* @param algorithm
|
|
* @param input
|
|
* @param key
|
|
* @param iv
|
|
* @return The decrypted input as a String.
|
|
*
|
|
* @throws InvalidKeyException
|
|
* @throws NoSuchAlgorithmException
|
|
* @throws NoSuchPaddingException
|
|
* @throws InvalidAlgorithmParameterException
|
|
* @throws IllegalBlockSizeException
|
|
* @throws BadPaddingException
|
|
*/
|
|
protected static String decryptString(String algorithm, byte[] input, SecretKey key, IvParameterSpec iv)
|
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
|
|
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
|
|
return new String(SQLiteEncryption.decryptByte(algorithm, input, key, iv));
|
|
}
|
|
|
|
protected static byte[] keyToByte(SecretKey key) {
|
|
return Base64.getEncoder().encode(key.getEncoded());
|
|
}
|
|
|
|
protected static SecretKey byteToKey(byte[] encodedKey) {
|
|
byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
|
|
return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
|
|
}
|
|
}
|