【发布时间】:2015-09-23 03:46:43
【问题描述】:
我有一个应用程序需要在配置文件中存储一些秘密密码,例如数据库和 ftp 密码/详细信息。我环顾四周,发现了很多使用 AES 的加密/解密解决方案,但我似乎无法弄清楚如何在不更改密钥的情况下使其工作。这意味着我可以加密和解密(使用相同的 SecretKey),但要在重启等过程中保持持久性。我似乎无法让 SecretKey 保持不变。下面的示例显示了我的方法的工作原理:
String secret = Encryptor.encrpytString("This is secret");
String test = Encryptor.decrpytString(secret);
System.out.println(test); //This is secret is printed
到目前为止一切顺利。但是,如果我运行它一次,我可能会得到“2Vhht/L80UlQ184S3rlAWw==”的值作为我的秘密,下一次它是“MeC4zCf9S5wUUKAu8rvpCQ==”,所以大概密钥正在改变。我假设我正在对问题应用一些反直觉的逻辑,如果有人能阐明a)我做错了什么,或者b)允许我存储加密密码信息的解决方案,我将不胜感激并且可以使用提供的信息进行检索。
我的方法如下:
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);
}
感谢您的帮助!
【问题讨论】:
标签: java encryption aes password-encryption