日期:2014-05-20  浏览次数:20892 次

请教java解密时的乱码问题
我在使用AES加密时正常,解密时明文也能解出来,但是密文后头总是跟着一个小尾巴
例如:
我的明文是:[大数据从业市场现状:薪酬增长 人才缺口巨大][Hadoop——Microsoft大数据战略的核心]
解密的文本是:[大数据从业市场现状:薪酬增长 人才缺口巨大][Hadoop——Microsoft大数据战略的核心]op——Microsoft
多出来的“op——Microsoft”不知道怎么来的,我怀疑是不是加密时最后一个分组字符数不足分组长度填充字符导致的乱码,问题是怎么去掉它?
我已经换过DESed,AES等算法,试过EBC,CBC等模式,包括填充算法都换了两种,都无法解决这个问题
另外:我用字符方式读写文件FileReader和FileWriter就不出现这个问题,这个问题就出现在二进制读写文件模式中

下面是我的源码:
加密代码:
public static void main(String args[]) throws Exception {
  //加密密钥是另外一个程序生成的
FileInputStream f = new FileInputStream("key1.dat");
ObjectInputStream ob = new ObjectInputStream(f);
Key k = (Key) ob.readObject();

byte[] rand = new byte[16];
Random r = new Random();
r.nextBytes(rand);
IvParameterSpec iv = new IvParameterSpec(rand);


FileOutputStream f2 = new FileOutputStream("iv.dat");
f2.write(rand);


Cipher cp = Cipher.getInstance("AES/CBC/PKCS5Padding","BC");
cp.init(Cipher.ENCRYPT_MODE, k, iv);

FileInputStream in = new FileInputStream("测试文本.txt");
FileOutputStream out = new FileOutputStream("加密测试文本2.txt");


byte buf[] = new byte[32];
int i = in.read(buf);
int j=1;
while (i ==32) {
byte ctext[] = cp.doFinal(buf);
// 为写文件做准备,为了防止出现读密文时的意外终止(此时会提示pad填充错误,或者块长度不正确),在写文件前将密文进行Base64编码
byte[] data = Base64.encodeBase64(ctext);
out.write(data);
i = in.read(buf);
j++;
}

//处理最后一个不足32字节的数据块
byte ctext[] = cp.doFinal(buf);
byte[] data = Base64.encodeBase64(ctext);
out.write(data);

  in.close();
out.close();

}

解密:
public static void main(String args[]) throws Exception {

FileInputStream f = new FileInputStream("key1.dat");
ObjectInputStream ob = new ObjectInputStream(f);
Key k = (Key) ob.readObject();

FileInputStream f2=new FileInputStream("iv.dat");
  byte[] rand=new byte[16];
  f2.read(rand);
  IvParameterSpec iv=new IvParameterSpec(rand);

  Cipher cp=Cipher.getInstance("AES/CBC/PKCS5Padding","BC");
  cp.init(Cipher.DECRYPT_MODE, k, iv);

FileInputStream in = new FileInputStream("加密测试文本2.txt");
FileOutputStream out = new FileOutputStream("解密测试文本2.txt");

byte buf[] = new byte[64];
int i = in.read(buf);



while (i == 64) {
// 为了防止出现读密文时的意外终止(此时会提示pad填充错误,或者块长度不正确),在写文件前将密文进行Base64编码,因此此处需解码
byte[] data = Base64.decodeBase64(buf);
byte ptext[] = cp.doFinal(data);


out.write(ptext);
i = in.read(buf);

}


in.close();
out.close();

}

------解决方案--------------------
会不会是分块加密的时候存在问题
------解决方案--------------------
FileInputStream in = new FileInputStream("加密测试文本2.txt");

读文件有问题,为什么不是全部读出来或者一起写进去,而是一块一块地去读?

建议看一下 CipherInputStream 和 CipherOutputStream 吧