首页 > 代码库 > Java 之 Given final block not properly padded

Java 之 Given final block not properly padded

  获取Cipher对象的时候一定要写成

  Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");

  不要写成

  Cipher cipher = Cipher.getInstance("DES");

  否则解密的时候会报错:

  Given final block not properly padded

 

  原因是Cipher cipher = Cipher.getInstance("DES");与Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");等同,填充方式错误,加密的时候会得到16长度的字节数组。

 

  解密的时候报错: javax.crypto.BadPaddingException:   Given   final   block   not   properly   padded 

  仔细分析一下,不难发现,该异常是在解密的时候抛出的,加密的方法没有问题。  

  但是两个方法的唯一差别是Cipher对象的模式不一样,这就排除了程序写错的可能性。再看一下异常的揭示信息,大概的意思是:提供的字块不符合填补的。

  原来在用DES加密的时候,最后一位长度不足64的,它会自动填补到64,那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以引发系统抛出异常。

  问题找到,怎么解决呢?大家还记得邮件传输通常会把一些信息编码保存,对了,就是Base64,那样保证了信息的完整性。为了方便使用,我们再写一个新的方法封装一下原来的方法:  

    public static String DataEncrypt(String str, byte[] key)    {          String encrypt = null;          try        {              byte[] ret = encode(str.getBytes("UTF-8"),key);              encrypt = new String(Base64.encode(ret));          }        catch(Exception e){              System.out.print(e);              encrypt = str;          }          return encrypt;      }
public static String DataDecrypt(String str, byte[] key) {   String decrypt = null;   try {   byte[] ret = decode(Base64.decode(str),key);   decrypt = new String(ret,"UTF-8");   } catch(Exception e) {   System.out.print(e);   decrypt = str;   }   return decrypt;   }  

  我们把方法的参数改成了字串,但是为什么要用UTF-8呢?不指定它的字节格式不行吗?大家知道,UTF-8是国际通用的字符编码,用它传输任何字串都不会有问题,通过它也可以很完美的解决J2EE的中文问题!所以我们最好用UTF-8编码,以减少不必要的麻烦。

Java 之 Given final block not properly padded