Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length not multiple of 8 bytes
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at TripleDES.desEncrypt(TripleDES.java:28)
at Test.main(Test.java:17)上代码:
import java.security.MessageDigest;
public class Test { /**
 * @param args
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String oStr = "aaaaaaaaaaaaaa";
String key = "admin1234";
key = MD5.MD5(key).substring(0,24);
System.out.println(key);
System.out.println(key.getBytes("UTF-8").length);
byte[] tDES = TripleDES.desEncrypt(oStr, key);
//System.out.println(Base64.encode(tDES));
System.out.println(TripleDES.deDeCrypt(new String(tDES), key));
}
}
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;public class TripleDES
{
public static byte[] desEncrypt(String message, String key) throws Exception {
System.out.println(key);
        Cipher cipher = Cipher.getInstance("DESede/CBC/Nopadding");
        DESedeKeySpec desKeySpec = new DESedeKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        //IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(message.getBytes("UTF-8"));
    }

public static byte[] deDeCrypt(String src, String key) { 
if (key == null || key.length() == 0) { 
throw new IllegalArgumentException("Key is empty!"); 

try { 
Cipher cipher = Cipher.getInstance("DESede/CBC/Nopadding"); 
DESedeKeySpec desKeySpec = new DESedeKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        //IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, secretKey); 
return cipher.doFinal(src.getBytes("UTF-8")); 
} catch (Exception e) { 
e.printStackTrace(); 
throw new RuntimeException("Decrypt failed!", e); 

}
}
求答案 o(╯□╰)o!!

解决方案 »

  1.   

    DESede/CBC/Nopadding你的填充模式不正确!DES、AES 或者 3DES 属于块加密算法,一般来说原文必须是 8 的整数倍,所以块加密算法除子加密模式之外,还涉及到一个填充模式。如果你一定要用 NoPadding 的话,那么必须保证原文字节是 8 的倍数,否则的话需要使用其他的填充模式。在 Sun JCE 中默认的填充模式除了 NoPadding 之外,还有:PKCS5Padding 和 ISO10126PaddingPKCS5Padding 的填充规则是:填充至符合块大小的整数倍,填充值为填充数量数。例如:
    原始:FF FF FF FF FF FF FF FF FF
    填充:FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07ISO10126Padding 的填充规则是:填充至符合块大小的整数倍,填充值最后一个字节为填充的数量数,其他字节随机处理。例如:
    原始:FF FF FF FF FF FF FF FF FF
    填充:FF FF FF FF FF FF FF FF FF 3F 7A B4 09 14 36 07
    使用填充模式后原文字节并不需要是 8 的整数倍,采用填充模式之后,块加密的密文长度为:(N / 8 * 8) + 8如上,假如原文长度为 15 个字节,密文长度就是 16 个字节。假如原文长度为 16 个字节,密文长度就为 24 个字节。也就是说,采用填充模式后必须进行填充,哪怕是 8 的整数倍。使用哪一种填充模式加密的,也必须采用哪种填充模式解密。另外,你的代码还有一个问题。你采用的是 CBC 加密模式,而 CBC 加密模式需要有一个 IV 参数(也就是初始化向量),这个值在加密时会随机生成,但必须保存下来,否则无法完成解密工作。建议采用 ECB 模式,或者在使用 CBC 时将初始化向量保存,在解密时使用。
      

  2.   

    我又看了一下,你这代码里的问题多多啊。加密解密方法参数中的密钥怎么会是一个字符串呢?3DES 也就是 DESede 的密钥由于需要经过 3 次的 DES 处理,因此长度应该得是 24 个字节,并不是一个字节串。
      

  3.   


    问哈ecb模式需要向量吗?
      

  4.   

    没明白你的意思 小弟才能java没多长时间 
    字节和字节串 有什么区别?
      

  5.   

    喔,这是java专区啊,难怪了。。这小衰。。
      

  6.   

    前面的问题已经解决 现在的问题是 那个填充规则 是怎么样的??有个什么公式可计算啊?
    ---------------------
    (N / 8 * 8) + 8如上,假如原文长度为 15 个字节,密文长度就是 16 个字节。假如原文长度为 16 个字节,密文长度就为 24 个字节。也就是说,采用填充模式后必须进行填充,哪怕是 8 的整数倍。
    ---------------
    我采用的是DESede/ECB/PKCS5Padding结果我测试了哈 发觉生成的填充值不一样啊难道是先填充 再加密的????
      

  7.   

    是的,先填充,再加密ECB 是不需要初始化向量 IV 的维基百科上有一些加密模式的介绍,主要看看那些图就能明白了:http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation