- Is this the best way to encrypt/decrypt data?
- And Is it good to store Generated InitVector and CipherText in database as Base64 String which is converted from byte[]?
import javax.crypto.SecretKeyFactory; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.*; import java.util.Random; import java.security.SecureRandom; import java.security.AlgorithmParameters; import javax.crypto.spec.IvParameterSpec; import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.util.Base64; public class MyClass { public static void main(String args[]) { //Encrypt EncryptHelper helper = new EncryptHelper(); EncryptedData a = helper.encrypt("key123", "This is the text to encrypt"); //Decrypt EncryptHelper helper1 = new EncryptHelper(); String b = helper1.decrypt("key123", a); System.out.println(b); } public static class EncryptedData { String _saltString; String _initVector; String _cipherText; public EncryptedData(String saltString, String initVector, String cipherText) { _saltString = saltString; _initVector = initVector; _cipherText = cipherText; } public String getSaltString() { return _saltString; } public String getInitVector() { return _initVector; } public String getCipherText() { return _cipherText; } } public static class EncryptHelper { public EncryptedData encrypt(String password, String data) { try { byte[] salt = generateSalt(); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); /* Encrypt the message. */ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); byte[] initVector = params.getParameterSpec(IvParameterSpec.class).getIV(); byte[] ciphertext = cipher.doFinal(data.getBytes("UTF-8")); return new EncryptedData(getBase64String(salt), getBase64String(initVector), getBase64String(ciphertext)); } catch(Exception ex) { System.out.println(ex.getMessage()); } return null; } public String decrypt(String password, EncryptedData b) { try { byte[] salt = getBase64Bytes(b.getSaltString()); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); //Get from EncryptedData byte[] initVector = getBase64Bytes(b.getInitVector()); byte[] cipherText = getBase64Bytes(b.getCipherText()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(initVector)); String plaintext = new String(cipher.doFinal(cipherText), "UTF-8"); return plaintext; } catch(Exception ex) { return ex.getMessage(); } } private String getBase64String(byte[] data) { byte[] encoded = Base64.getEncoder().encode(data); return new String(encoded); } private byte[] getBase64Bytes(String str) { return Base64.getDecoder().decode(str); } private byte[] generateSalt() { final Random r = new SecureRandom(); byte[] salt = new byte[32]; r.nextBytes(salt); return salt; } } }