用AES 或DES解密文件字节数组 总是Given final block not properly padded 求解决

猪猪Zz 2013-04-28 04:01:01
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
public class Encrypted {
static Key key;
/**
* @param args
*/
public Encrypted(){
String s = "firewall";
Encrypted.getKey(s);
}
public byte[] getByteHex(byte[] byteS) {
byte[] min = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
min = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return min;
}
public byte[] getDesCode(byte[] b) {
Cipher cipher;
byte[] byteFina = null;
try {

cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(b);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
public static void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("AES");
_generator.init(new SecureRandom(strKey.getBytes()));
key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根

}

}

我想实现文件分组字节加密后传输,下载时文件分组解密。。解密时总是报错
...全文
46420 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
li-Struggle 2015-12-18
  • 打赏
  • 举报
回复
谢谢!! KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom random=SecureRandom.getInstance("SHA1PRNG"); random.setSeed(key.getBytes()); kgen.init(128, random);加密解密时都加上OK了
xueya1 2015-07-27
  • 打赏
  • 举报
回复
加解密都需要加 否则会出现不同服务器不一致的情况 KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom random=SecureRandom.getInstance("SHA1PRNG"); random.setSeed(key.getBytes()); kgen.init(128, random);
taolei 2013-04-30
  • 打赏
  • 举报
回复
说明一下,如果加密/解密时不指定填充方式,则加密/解密的数据必需是块长度的整数倍,否则会出现你遇到的错误。
taolei 2013-04-30
  • 打赏
  • 举报
回复
块加密算法有三个相关选项。 1、算法 AES/DES/DESede等 2、分组模式 ECB/CBC等。ECB模式每块单独加密,相同的明文会产生相同的密文,不安全。通常用CBC模式(其他模式也可选),CBC模式需要设置一个和块长度相等初始向量(数组)。该向量通常以明文的方式和密文一起给解密者,不同的初始向量可以使相同的明文每次都产生不同的密文。 3、填充模式。块加密时以块为单位的(ASE是128位,16个字节),加密数据最后要添加数据使长度是块长度的整数倍,并且在解密时根据填充的数据可计算出实际的数据长度。通常使用PKCS5PADDING填充算法(也有其他模式可选)。 以上内容如果想了解细节内容请自己百度,网上有许多相关文章。 简单的加密解密可参考如下代码

static byte[] wrap(String algo,byte[] key,byte[] iv,byte[] data,int mode) throws Exception
	{
		Cipher cipher = Cipher.getInstance(algo + "/CBC/PKCS5PADDING");
		SecretKeySpec skey = new SecretKeySpec(key,0,Math.min(key.length,Cipher.getMaxAllowedKeyLength(algo)/8),algo);
		IvParameterSpec ivParam = new IvParameterSpec(iv,0,cipher.getBlockSize());
		cipher.init(mode,skey,ivParam);
		return cipher.doFinal(data);
	}
	static byte[] encrypt(String algo,byte[] key,byte[] iv,byte[] data) throws Exception
	{
		return wrap(algo,key,iv,data,Cipher.ENCRYPT_MODE);
	}
	static byte[] decrypt(String algo,byte[] key,byte[] iv,byte[] data) throws Exception
	{
		return wrap(algo,key,iv,data,Cipher.DECRYPT_MODE);
	}
	static byte[] key(String key) throws Exception
	{
		return MessageDigest.getInstance("MD5").digest(key.getBytes("UTF-8"));
	}
	static byte[] iv(long iv)
	{
		byte[] b = new byte[32];
		ByteBuffer.wrap(b).putLong(iv);
		return b;
	}
	static byte[] encrypt(String algo,String key,long iv,String text) throws Exception
	{
		return encrypt(algo,key(key),iv(iv),text.getBytes("UTF-8"));
	}
	static String decrypt(String algo,String key,long iv,byte[] data) throws Exception
	{
		return new String(decrypt(algo,key(key),iv(iv),data),"UTF-8");
	}
	public static void main(String[] args) throws Exception
	{
		//初始向量需要明文传递给解密者,以使相同的明文每次都产生不同的密文。
		for(int i=0;i<8;i++)
		{
			String algo = i<4?"AES":"DES";
			//long iv = System.nanoTime();
			long iv = i; //每次运行都会输出相同结果
			byte[] data = encrypt(algo,"mypassword",iv,algo +" encrypt/decrypt sample.");
			System.out.print("iv=" + Long.toHexString(iv) + "\t");
			for(byte b:data)
				System.out.print(" " + Integer.toHexString(0x100|(0xff&b)).substring(1));
			System.out.println();
			String text = decrypt(algo,"mypassword",iv,data);
			System.out.println(text);
		}
	}
猪猪Zz 2013-04-30
  • 打赏
  • 举报
回复
用了 base64 还是解密不了 while(true) { read=reader.read(buf); if(read==-1) break; 想在这插入解密函数 但是始终报错 求能对文件流 加解密函数 outfile.write(buf, 0, read); }
Mitos_Yggdrasill 2013-04-28
  • 打赏
  • 举报
回复
我也遇到这个问题……
  • 打赏
  • 举报
回复
DES加密的时候如果一位长度不足64的,它会自动填补到64。解密的时候,会解析你填补的不可见字符。所以就报“提供的字块不符合填补的”异常了。可以尝试用Base64包装一下。 http://stackoverflow.com/questions/8049872/given-final-block-not-properly-padded http://hi.baidu.com/roadsea/item/ae8e801f5d540aca39cb30e7

50,549

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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