文件加密Java [英] Files Encryption Java

查看:157
本文介绍了文件加密Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



这是我的尝试:

  public class AesEncrDec 
{

public static String encrypt(String Data)
{
byte [] byteCipherText = null;
try {
String plainData = Data,cipherText,decryptptedText;
KeyGenerator keyGen = KeyGenerator.getInstance(AES);
keyGen.init(128);
SecureRandom rnd = new SecureRandom();
SecretKey secretKey = keyGen.generateKey();
IvParameterSpec iv;
iv = new IvParameterSpec(rnd.generateSeed(16));
密码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));
密码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这里是错误

  2014年3月24日6:27:42 PM PrefsReadAndWrite.AesEncrDec解密
SEVERE:null
javax .crypto.BadPaddingException:给定最终块没有正确填充
在com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
在com.sun.crypto.provider.CipherCore.doFinal (CipherCore.java:824)
在com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
在javax.crypto.Cipher.doFinal(Cipher.java:2121)
在PrefsReadAndWrite.AesEncrDec.decrypt(AesEncrDec.java:61)
在PrefsReadAndWrite.AesEncrDec.decryptedString(AesEncrDec.java:104)
在smarthouse.SmartHouse.main(SmartHouse.java:12)

线程main中的异常java.lang.NullPointerException
在java.lang.String。< init>(String.java:554)
在PrefsReadAndWrite.AesEncrDec。 secretedString(AesEncrDec.java:105)
在smarth ouse.SmartHouse.main(SmartHouse.java:12)
Java结果:1


解决方案

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



应用AppSecurity类生成新密钥,加密/解密

  public class AppSecurity {
private AppSecurity(){}

public static byte [] encrypt(byte [] key,byte [] data){
SecretKeySpec keySpec = new SecretKeySpec(key,AES);
尝试{
密码密码= 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){}
返回null;
}

public static byte [] decrypt(byte [] key,byte [] encryptedData){
SecretKeySpec keySpec = new SecretKeySpec(key,AES);
尝试{
密码密码= 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){}
返回null;
}

/ **
*方法生成一个安全密钥。在应用程序启动时调用此函数
* @return
* /
public static byte [] generateKey(){
try {
//创建一个AES算法实例。
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 decryptptedString(byte [] blob){
//这里的getSecretKey()应该是使用的加密
byte [] decryptpted = AppSecurity.decrypt(YourApplication.getSecretKey(),blob);
返回toString(解密);

}



将字节转换为字符串

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

将字符串转换为字节的方法

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

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

假设类名称为 YourApplication.java

  //在应用程序启动时初始化
String mSecretKey = initSecurity()

//加密/解密
时调用此方法public static byte [] getSecretKey(){return mSecretKey; }

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

  private void initSecurity(){
final String secretFile =secure_file;
boolean keyExists = false;
//检查安全文件中是否存在密钥
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){
//生成一个键
mSecretKey = AppSecurity.generateKey();
if(mSecretKey!= null){
//写入应用程序内的安全文件
try {
// MODE_PRIVATE将创建文件(或替换文件同名)
//并使其对应用程序是私有的。
FileOutputStream outputStream = openFileOutput(secretFile,Context.MODE_PRIVATE);
outputStream.write(mSecretKey);
outputStream.close();
}
catch(FileNotFoundException e){}
catch(IOException e){}
}
}
}


I'm making a system that has some data in it, and I want it to take this data (in XML format) and save it as an encrypted string in a txt file, and later on when the software opens again, decrypt the file and read it as normal. I already have all the code to convert the xml to a string, I already have the code to save it, I just need some help with the encryption/decryption code?

Note: I did find some code to encrypt/decrypt, but it seems that I can't split the code into 2 methods.

Here is my attempt:

    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);
}
}

EDIT : In responce to @Libin here are the errors

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

解决方案

You have to generate the key only once and use it for encrypt and decrypt.. Use this code ...

AppSecurity class should be used to generate new key and 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;
    }
  }
}

Method to Encrypt the string.

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

Method to Decrypt the byte.

  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);

     }

Method to convert Byte to String

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

Method to convert String to Byte

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

Detail on how to use this in your application : initialize initSecurity() method on your application/applet class and store the return key into a variable and make use of this on runtime.

Assuming class name as YourApplication.java

 // initialize it on your app startup
 String mSecretKey = initSecurity()

 // call this method when you encrypt /decrypt
 public static byte[] getSecretKey() { return mSecretKey; } 

//Add this method to read from file or generate one new key

 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) {}
        }
    }
}

这篇关于文件加密Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆