我正在制作一个系统,其中包含一些数据,我希望它能够接受这些数据( XML格式),并将其保存为txt文件中的加密字符串,然后当软件再次打开时,解密该文件并将其正常读取。我已经有了将xml转换成字符串的所有代码,我已经有了保存它的代码,我只需要一些加密/解密代码的帮助吗?
注意:我确实找到了一些可以加密/解密的代码,但是我似乎不能将代码分成两个方法。
以下是我的尝试:
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.<init>(String.java:554)
at PrefsReadAndWrite.AesEncrDec.decryptedString(AesEncrDec.java:105)
at smarthouse.SmartHouse.main(SmartHouse.java:12)
Java Result: 1发布于 2014-03-24 20:55:09
您必须只生成一次密钥,并将其用于加密和解密。用这个代码..。
应该使用AppSecurity类来生成新密钥和加密/解密
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);}
方法将字节转换为字符串。
public static String toString(byte[] bytes) {
try {
String s = new String(bytes ,"UTF-8");
return s;
} catch (UnsupportedEncodingException e) {
return null;
}
}方法将字符串转换为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) {}
}
}
}发布于 2014-03-24 20:33:21
您没有定义要使用的填充,因此使用了实现定义的填充。根据您的错误,在您的情况下,这可能是"NoPadding“。指定填充和操作方式,例如AES/CBC/PKCS5Padding。由于您现在将使用CBC,您还需要一个初始化向量:
IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16));
aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,iv);其中rnd是一个SecureRandom实例。同样,将数据作为字符串返回也是个坏主意,直接使用字节。当然,按照Libin的建议使用相同的密钥进行加密和解密。
https://stackoverflow.com/questions/22619602
复制相似问题