AES对文件加解密

hucainiao 2012-02-10 11:34:47
package com.zbwt.archives.util.encrypteDecryption;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class AESTwo {
private static KeyGenerator kgen;
private static SecureRandom secureRandom;
private static SecretKeySpec key;
private static Cipher cipher;
/**
* AES加密算法
*/
public AESTwo() {
}
private static void init(String keyWord){
try {
kgen = KeyGenerator.getInstance("AES");
secureRandom = SecureRandom.getInstance("SHA1PRNG" );
secureRandom.setSeed(keyWord.getBytes());
kgen.init(128,secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
key = new SecretKeySpec(enCodeFormat, "AES");
cipher = Cipher.getInstance("AES");// 创建密码器
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/********************************对文件进行加密解密*********************************************************/
/**
* @param fileName 加密的文件路径
* @param fileNameEncrypt 加密后的文件路径 当fileNameEncrypt为null时加密文件代替原文件
* @param keyWord 加密密钥
*
*/
public static void encryptFile(String fileName,String fileNameEncrypt, String keyWord){
try {
boolean replace = false;
if(fileNameEncrypt==null || fileNameEncrypt.equals("")){
fileNameEncrypt = fileName+".tem";
replace = true;
}
init(keyWord);
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
File file = new File(fileNameEncrypt);
if (!file.exists())
file.createNewFile();
FileInputStream fileinputstream=new FileInputStream(fileName);
FileOutputStream out = new FileOutputStream(file);
byte bytes[] = new byte[131072]; //因在断点下载时用到,不能修改 除非 断点下载处修改
byte enbytes[] = null;
int line = 0;
while ((line = fileinputstream.read(bytes)) != -1) {
enbytes = cipher.doFinal(Arrays.copyOfRange(bytes, 0, line));
out.write(enbytes, 0, enbytes.length);
}
out.close();
fileinputstream.close();

if(replace){
File oldFile = new File(fileName);
oldFile.delete();
File newFile = new File(fileNameEncrypt);
newFile.renameTo(oldFile);
}

} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/**解密
* @param content 待解密内容
* @param keyWord 解密密钥
* @return byte[]
*/
public static void decryptFile(String encryptFileName,String decryptFileName, String keyWord) {
try {
boolean replace = false;
if(decryptFileName==null || decryptFileName.equals("")){
decryptFileName = encryptFileName+".tem";
replace = true;
}
init(keyWord);
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
File file = new File(decryptFileName); //解密后的文件
if (!file.exists())
file.createNewFile();
FileInputStream fileinputstream=new FileInputStream(encryptFileName); //要解密的文件
FileOutputStream out = new FileOutputStream(file);
byte bytes[] = new byte[131080]; //因在断点下载时用到,不能修改 除非 断点下载处修改
byte enbytes[] = null;
int line = 0;
while ((line = fileinputstream.read(bytes)) != -1) {
enbytes = cipher.doFinal(Arrays.copyOfRange(bytes, 0, line));
out.write(enbytes, 0, enbytes.length);
}
out.close();
fileinputstream.close();

if(replace){
File oldFile = new File(encryptFileName);
oldFile.delete();
File newFile = new File(decryptFileName);
newFile.renameTo(oldFile);
}
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

/********************************对文件进行加密解密结束*****************************************************/

/**将二进制转换成16进制
* @param buf
* @return String
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**将16进制转换为二进制
* @param hexStr
* @return byte[]
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++) {
int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}

public static void main(String[] args) {
AESTwo.encryptFile("D:\\tcas4home\\certificateKey\\jingoal.rar", "D:\\tcas4home\\certificateKey\\复件 (2) jingoal.rar", "ABCDEFGHABCDEFGH");
AESTwo.decryptFile("D:\\tcas4home\\certificateKey\\复件 (2) jingoal.rar", "D:\\tcas4home\\certificateKey\\复件 jingoal.rar", "ABCDEFGHABCDEFGH");
}
}

报异常:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
在网上搜的错误原因说是
这主要是因为加密后的byte数组是不能强制转换成字符串的,换言之:字符串和byte数组在这种情况下不是互逆的;可是没看出上述程序有什么逆转啊

还有我现在解密时读的字节流是 byte bytes[] = new byte[131080]; 如果把 131080改成 131088就不报错了 可是因为项目中这个 131080因为在文件下载时需要支持断点下载 所以给写死了 无法修改。纠结啊。。
还有一种情况不报错,就是 在上述程序中 文件小于 128kb时加解密都没问题

高分求牛人 解决。。。。。。。。。。。。。。。。。。。。。。。。。。
...全文
265 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
hucainiao 2012-02-10
  • 打赏
  • 举报
回复
那个不用管 ,就是现在报的异常怎么解觉 是不是网上说的那个异常的原因啊??、
healer_kx 2012-02-10
  • 打赏
  • 举报
回复
我试了一下,但是不知道怎么改,因为不知道和断点下载什么的有啥关系。

断点续传?
healer_kx 2012-02-10
  • 打赏
  • 举报
回复
我试了一下,但是不知道怎么改,因为不知道和断点下载什么的有啥关系。

断点续传?
hucainiao 2012-02-10
  • 打赏
  • 举报
回复
嗯 感谢啊 快纠结死了
healer_kx 2012-02-10
  • 打赏
  • 举报
回复
帮你调试一下?
hucainiao 2012-02-10
  • 打赏
  • 举报
回复
上述的程序 运行main方法 当加密文件大于 128kb时,对加密后的文件解密 就报上述的异常
healer_kx 2012-02-10
  • 打赏
  • 举报
回复
没懂你的意思,好复杂啊。

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧