AES文件加密(跨平台)

多平台下AES文件加密的总结,涵盖Windows,Android,Mac,Linux。。

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;

import javax.crypto.CipherInputStream;

import javax.crypto.CipherOutputStream;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

public class AESCrpyt {

private static String TYPE = "AES";

private static int KeySizeAES128 = 16; 

private static int BUFFER_SIZE = 8192;         

private static Cipher getCipher(int mode,String key) {

//mode =Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE

Cipher mCipher;

byte[]keyPtr=new byte[KeySizeAES128];

IvParameterSpecivParam=new IvParameterSpec(keyPtr);

byte[]passPtr=key.getBytes();

try{

mCipher=Cipher.getInstance(TYPE+"/CBC/PKCS5Padding");

for(int i=0;i<KeySizeAES128;i++) {

if(i<passPtr.length) keyPtr[i]=passPtr[i];

else keyPtr[i]=0;

}

SecretKeySpec keySpec=new SecretKeySpec(keyPtr,TYPE);

mCipher.init(mode, keySpec, ivParam);

return mCipher;

catch (InvalidKeyException e) {

e.printStackTrace();

catch (NoSuchAlgorithmException e) {

e.printStackTrace();

catch (NoSuchPaddingException e) {

e.printStackTrace();

catch (InvalidAlgorithmParameterException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

/**

* 解密文件

* @param srcFile

* @param destFile

* @param privateKey

*/

public static void decrypt(String srcFile, String destFile, String privateKey) {   

byte[] readBuffer=new byte[BUFFER_SIZE];

Cipher deCipher=getCipher(Cipher.DECRYPT_MODE,privateKey);

if(deCipher==null) return; //init failed.

CipherInputStream fis=null;

BufferedOutputStream fos=null; 

int size;

try {   

fis = new CipherInputStream(

new BufferedInputStream(

new FileInputStream(srcFile)),deCipher);   

fos = new BufferedOutputStream(

new FileOutputStream(mkdirFiles(destFile)));   

while((size=fis.read(readBuffer,0,BUFFER_SIZE))>=0) {

fos.write(readBuffer,0,size);

}

fos.flush();

} catch (FileNotFoundException e) {   

e.printStackTrace();   

} catch (IOException e) {   

e.printStackTrace();   

} finally {   

if (fis != null) {

try { fis.close(); } catch(IOException e) {}   

}   

if (fos != null) {

try { fos.flush(); } catch(IOException e) {}

try { fos.close(); } catch(IOException e) {}

}   

}   

}

/**

* 加密文件

* @param srcFile

* @param destFile

* @param privateKey

*/

public static void crypt(String srcFile, String destFile, String privateKey) {   

byte[] readBuffer=new byte[BUFFER_SIZE];

Cipher enCipher=getCipher(Cipher.ENCRYPT_MODE,privateKey);

if(enCipher==null) return; //init failed.

CipherOutputStream fos=null;

BufferedInputStream fis=null;

int size;

try {   

fos = new CipherOutputStream(

new BufferedOutputStream(

new FileOutputStream(destFile)),enCipher);   

fis = new BufferedInputStream(

new FileInputStream(mkdirFiles(srcFile)));   

while((size=fis.read(readBuffer,0,BUFFER_SIZE))>=0) {

fos.write(readBuffer,0,size);

}

fos.flush();

} catch (FileNotFoundException e) {   

e.printStackTrace();   

} catch (IOException e) {   

e.printStackTrace();   

} finally {   

if (fis != null) {

try { fis.close(); } catch(IOException e) {}   

}   

if (fos != null) {

try { fos.flush(); } catch(IOException e) {}

try { fos.close(); } catch(IOException e) {}

}   

}   

}

private static File mkdirFiles(String filePath) throws IOException {   

File file = new File(filePath);   

if (!file.getParentFile().exists()) {   

file.getParentFile().mkdirs();

}   

file.createNewFile();

return file;

}

public static void main(String[] args) {

AESCrpyt aes = new AESCrpyt();

aes.crypt("/Users/liaomin/Documents/计算机原理.pdf", "/Users/liaomin/Documents/加密_计算机原理.pdf", "111");

aes.decrypt("/Users/liaomin/Documents/加密_计算机原理.pdf", "/Users/liaomin/Documents/解密_计算机原理.pdf", "111");

}

}

 测试了在Windows,Android,Linux,Mac下都能正常的使用。

另外Cipher实例化时,模式一定得选CBC模式,如果选择ECB模式,否则在某些平台无法正常使用,测试了在Mac平台下会报java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV 异常。

为此顺带了解了下ECB和CBC模式,ECB是一种字符串分割方式,是加密方式通常采用的一种分割方式,主要是DES等加密方式采用这种方式。

而AES 下的CBC模式则是比ECB模式下衍生出来的一种模式。

CBC这种操作模式,它是在ECB加密的密文的每个数据块进行异或运算与下一个明文块进行加密,从而使所有的块依赖于以前的所有块。这意味着,为了找到一个特定块的明文,则需要知道的密文,密钥和密文对前块。要被加密的第一数据块没有先前的密文,所以明文异或与所谓的初始化向量的64位数字,或IV的简称。因此,如果数据传输通过网络或电话线,有一个传输错误(添加或删除位元) ,该错误将被结转到所有后续块,因为每个块是取决于最后。如果该位被修改只是在运输过程中(这是比较常见的情况下)的错误,只会影响到所有在更改块的位,并在下面的块中的相应位。该错误不传播任何进一步。这种操作模式是比ECB更安全的,因为额外的异或步骤加上一个更多层的加密处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值