package com.softgate.crypt; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.security.MessageDigest; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * A simple utility class for easily encrypting and decrypting data using the AES algorithm. * * @author Chad Adams */ public class AESUtils { /** * The constant that denotes the algorithm being used. */ private static final String algorithm = "AES"; /** * The private constructor to prevent instantiation of this object. */ private AESUtils() { } /** * The method that will generate a random {@link SecretKey}. * * @return The key generated. */ public static SecretKey generateKey() { try { KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm); keyGenerator.init(128); return keyGenerator.generateKey(); } catch (Exception ex) { } return null; } /** * Creates a new {@link SecretKey} based on a password. * * @param password * The password that will be the {@link SecretKey}. * * @return The key. */ public static SecretKey createKey(String password) { try { byte[] key = password.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit return new SecretKeySpec(key, algorithm); } catch (Exception ex) { } return null; } /** * Creates a new {@link SecretKey} based on a password with a specified salt. * * @param salt * The random salt. * * @param password * The password that will be the {@link SecretKey}. * * @return The key. */ public static SecretKey createKey(byte[] salt, String password) { try { byte[] key = (salt + password).getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit return new SecretKeySpec(key, algorithm); } catch (Exception ex) { } return null; } /** * The method that writes the {@link SecretKey} to a file. * * @param key * The key to write. * * @param file * The file to create. * * @throws IOException * If the file could not be created. */ public static void writeKey(SecretKey key, File file) throws IOException { try (FileOutputStream fis = new FileOutputStream(file)) { fis.write(key.getEncoded()); } } /** * Gets a {@link SecretKey} from a {@link File}. * * @param file * The file that is encoded as a key. * * @throws IOException * The exception thrown if the file could not be read as a {@link SecretKey}. * * @return The key. */ public static SecretKey getSecretKey(File file) throws IOException { return new SecretKeySpec(Files.readAllBytes(file.toPath()), algorithm); } /** * The method that will encrypt data. * * @param secretKey * The key used to encrypt the data. * * @param data * The data to encrypt. * * @return The encrypted data. */ public static byte[] encrypt(SecretKey secretKey, byte[] data) { try { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(data); } catch (Exception ex) { } return null; } /** * The method that will decrypt a piece of encrypted data. * * @param password * The password used to decrypt the data. * * @param encrypted * The encrypted data. * * @return The decrypted data. */ public static byte[] decrypt(String password, byte[] encrypted) { try { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, AESUtils.createKey(password)); return cipher.doFinal(encrypted); } catch (Exception ex) { } return null; } /** * The method that will decrypt a piece of encrypted data. * * @param secretKey * The key used to decrypt encrypted data. * * @param encrypted * The encrypted data. * * @return The decrypted data. */ public static byte[] decrypt(SecretKey secretKey, byte[] encrypted) { try { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, secretKey); return cipher.doFinal(encrypted); } catch (Exception ex) { } return null; } }