文件加密Java

我正在制作一个包含一些数据的系统,我希望它采用这种数据(XML格式)并将其保存为txt文件中的加密字符串,稍后当软件再次打开时,解密文件并正常阅读。 我已经拥有将xml转换为字符串的所有代码,我已经有了保存它的代码,我只需要一些加密/解密代码的帮助?

注意:我确实找到了一些加密/解密的代码,但似乎我无法将代码拆分为2种方法。

这是我的尝试:

public class AesEncrDec { public static String encrypt(String Data) { byte[] byteCipherText = null; try { String plainData=Data,cipherText,decryptedText; KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(128); SecureRandom rnd = new SecureRandom(); SecretKey secretKey = keyGen.generateKey(); IvParameterSpec iv; iv = new IvParameterSpec(rnd.generateSeed(16)); Cipher aesCipher = Cipher.getInstance("AES"); aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,iv); byte[] byteDataToEncrypt = plainData.getBytes(); byteCipherText = aesCipher.doFinal(byteDataToEncrypt); cipherText = new BASE64Encoder().encode(byteCipherText); return new String(byteCipherText); } catch (InvalidKeyException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchPaddingException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalBlockSizeException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (BadPaddingException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } return new String(byteCipherText); } public static String dencrypt(String Data) { byte[] byteDecryptedText = null; try { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(128); IvParameterSpec iv; SecureRandom rnd = new SecureRandom(); iv = new IvParameterSpec(rnd.generateSeed(16)); Cipher aesCipher = Cipher.getInstance("AES"); SecretKey secretKey = keyGen.generateKey(); aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,iv); byteDecryptedText = aesCipher.doFinal(Data.getBytes()); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchPaddingException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (InvalidKeyException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (InvalidAlgorithmParameterException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalBlockSizeException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } catch (BadPaddingException ex) { Logger.getLogger(AesEncrDec.class.getName()).log(Level.SEVERE, null, ex); } return new String(byteDecryptedText); } } 

编辑:在回答@Libin这里是错误

 Mar 24, 2014 6:27:42 PM PrefsReadAndWrite.AesEncrDec decrypt SEVERE: null javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436) at javax.crypto.Cipher.doFinal(Cipher.java:2121) at PrefsReadAndWrite.AesEncrDec.decrypt(AesEncrDec.java:61) at PrefsReadAndWrite.AesEncrDec.decryptedString(AesEncrDec.java:104) at smarthouse.SmartHouse.main(SmartHouse.java:12) Exception in thread "main" java.lang.NullPointerException at java.lang.String.(String.java:554) at PrefsReadAndWrite.AesEncrDec.decryptedString(AesEncrDec.java:105) at smarthouse.SmartHouse.main(SmartHouse.java:12) Java Result: 1 

您只需生成一次密钥并将其用于加密和解密。使用此代码…

AppSecurity类应该用于生成新密钥和Encrypt / Decrypt

 public class AppSecurity{ private AppSecurity() {} public static byte[] encrypt(byte[] key , byte[] data) { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); try { Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE,keySpec); return cipher.doFinal(data); } catch (NoSuchAlgorithmException e){ } catch (NoSuchPaddingException e){ } catch (InvalidKeyException e){ } catch (BadPaddingException e){ } catch (IllegalBlockSizeException e) {} return null; } public static byte[] decrypt(byte[] key , byte[] encryptedData) { SecretKeySpec keySpec = new SecretKeySpec(key ,"AES"); try { Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, keySpec); return cipher.doFinal(encryptedData); } catch (NoSuchAlgorithmException e) {} catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { } catch (BadPaddingException e) {} catch (IllegalBlockSizeException e) {} return null; } /** * method to generate a secure key. call this when app starts * @return */ public static byte[] generateKey(){ try{ // create an AES algorithm instance. KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); keyGenerator.init(128,secureRandom); SecretKey secretKey = keyGenerator.generateKey(); return secretKey.getEncoded(); } catch (NoSuchAlgorithmException e){ return null; } } } 

加密字符串的方法。

  private static byte[] encryptedByte(String s) { return AppSecurity.encrypt(YourApplication.getSecretKey(),toBytes(s)); } 

解密字节的方法。

  private static String decryptedString(byte[] blob) { // here getSecretKey() should be the one used on encryption byte[] decrypted = AppSecurity.decrypt(YourApplication.getSecretKey(),blob); return toString(decrypted); 

}

将Byte转换为String的方法

 public static String toString(byte[] bytes) { try { String s = new String(bytes ,"UTF-8"); return s; } catch (UnsupportedEncodingException e) { return null; } } 

将String转换为Byte的方法

  public static byte[] toBytes(String s) { try { return s.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) {return null;} } 

有关如何在应用程序中使用它的详细信息:在应用程序/ applet类上初始化initSecurity()方法,并将返回键存储到变量中,并在运行时使用它。

假设类名为YourApplication.java

  // initialize it on your app startup String mSecretKey = initSecurity() // call this method when you encrypt /decrypt public static byte[] getSecretKey() { return mSecretKey; } 

//添加此方法以从文件中读取或生成一个新密钥

  private void initSecurity() { final String secretFile = "secure_file"; boolean keyExists = false; //check if secret key exist in secure file try { FileInputStream inputStream = openFileInput(secretFile); mSecretKey = new byte[16]; int result = inputStream.read(mSecretKey); if(result >0) { keyExists = true; } inputStream.close(); } catch (FileNotFoundException e) {} catch (IOException e){} if(!keyExists) { // generate a key mSecretKey = AppSecurity.generateKey(); if(mSecretKey != null) { // write in a secure file inside the app try { // MODE_PRIVATE will create the file (or replace a file of the same name) // and make it private to the application. FileOutputStream outputStream = openFileOutput(secretFile,Context.MODE_PRIVATE); outputStream.write(mSecretKey); outputStream.close(); } catch (FileNotFoundException e){} catch (IOException e) {} } } } 

您没有定义要使用的填充,因此使用实现定义的填充。 根据你的错误,这可能是你的情况下的“NoPadding”。 指定填充和操作模式,例如AES/CBC/PKCS5Padding 。 既然你现在将使用CBC,你还需要一个初始化向量:

 IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16)); aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,iv); 

其中rndSecureRandom实例。 将数据作为String返回是一个坏主意,直接使用字节。 当然,遵循Libins建议使用相同的密钥进行加密和解密。