I have an application that needs to store some secret passwords in a configuration file such as database and ftp passwords/detail. I've looked around and found a lot of encryption/decryption solutions using AES, but I can't seem to figure out how to make it work without changing the key. That means I can encrypt and decrypt (using the same SecretKey), but to maintain persistence across restarts etc. I can't seem to make the SecretKey stay the same. The example below shows my methods working:
String secret = Encryptor.encrpytString("This is secret"); String test = Encryptor.decrpytString(secret); System.out.println(test); //This is secret is printed So far so good. However if I run it once I might get the value of '2Vhht/L80UlQ184S3rlAWw==' as my secret, the next time it is 'MeC4zCf9S5wUUKAu8rvpCQ==', so presumably the key is changing. I'm assuming I am applying some counter-intuative logic to the problem and would appreciate if someone can shed some light on either a) what I'm doing wrong, or b) a solution that would allow me to store the password information encrypted and retrievable with the information provided.
My methods are as follows:
private static final String salt = "SaltySalt"; private static byte [] ivBytes = null; private static byte[] getSaltBytes() throws Exception { return salt.getBytes("UTF-8"); } private static char[] getMasterPassword() { return "SuperSecretPassword".toCharArray(); } private static byte[] getIvBytes() throws Exception { if (ivBytes == null) { //I don't have the parameters, so I'll generate a dummy encryption to create them encrpytString("test"); } return ivBytes; } public static String encrpytString (String input) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536,256); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); ivBytes = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV(); byte[] encryptedTextBytes = cipher.doFinal(input.getBytes("UTF-8")); return DatatypeConverter.printBase64Binary(encryptedTextBytes); } public static String decrpytString (String input) throws Exception { byte[] encryptedTextBytes = DatatypeConverter.parseBase64Binary(input); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536, 256); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(getIvBytes())); byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes); return new String(decryptedTextBytes); } Thanks for the help!