AES加密跨平台出现的问题

javax.crypto.BadPaddingException: Given final block not properly padded

       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*..)
       at chb.test.crypto.AESUtils.crypt(AESUtils.java:386)
       at chb.test.crypto.AESUtils.AesDecrypt(AESUtils.java:254)
       at chb.test.crypto.AESUtils.main(AESUtils.java:40) 

 

解决方法:

 

经过检查之后,定位在生成KEY的方法上,如下:

viw plaincopy to clipboardprint?

  1. public static SecretKey getKey (String strKey) {  

  2.  

  3.          try {           

  4.  

  5.             KeyGenerator _generator = KeyGenerator.getInstance( "AES" );  

  6.  

  7.             _generator.init(128new SecureRandom(strKey.getBytes()));  

  8.  

  9.                 return _generator.generateKey();  

  10.  

  11.         }  catch (Exception e) {  

  12.  

  13.              throw new RuntimeException( " 初始化密钥出现异常 " );  

  14.  

  15.         }  

  16.  

  17.       }   

  18.  

 

修改到如下方式,问题解决:

view plaincopy to clipboardprint?

  1.  

  2. public static SecretKey getKey(String strKey) {  

  3.  

  4.        try {           

  5.  

  6.           KeyGenerator _generator = KeyGenerator.getInstance( "AES" );  

  7.  

  8.            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );  

  9.  

  10.           secureRandom.setSeed(strKey.getBytes());  

  11.  

  12.           _generator.init(128,secureRandom);  

  13.  

  14.               return _generator.generateKey();  

  15.  

  16.       }  catch (Exception e) {  

  17.  

  18.            throw new RuntimeException( " 初始化密钥出现异常 " );  

  19.  

  20.       }  

  21.  

  22.     }   

  23.  

 

 

原因分析

SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。

一般情况下

package util;

 

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

 

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 AESUtil {

 

/**

    * 加密

    * 

    * @param content 需要加密的内容

    * @param password  加密密码

    * @return

    */

   public static byte[] encrypt(String content, String password) {

           try {           

                   KeyGenerator kgen = KeyGenerator.getInstance("AES");

                   //kgen.init(128, new SecureRandom(password.getBytes()));

                   

                   SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );  

                   secureRandom.setSeed(password.getBytes());  

                   kgen.init(128,secureRandom);

               

                   

                   

                   SecretKey secretKey = kgen.generateKey();

                   byte[] enCodeFormat = secretKey.getEncoded();

                   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

                   Cipher cipher = Cipher.getInstance("AES");// 创建密码器

                   byte[] byteContent = content.getBytes("utf-8");

                   cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化

                   byte[] result = cipher.doFinal(byteContent);

                   return result; // 加密

           } catch (NoSuchAlgorithmException e) {

                   e.printStackTrace();

           } catch (NoSuchPaddingException e) {

                   e.printStackTrace();

           } catch (InvalidKeyException e) {

                   e.printStackTrace();

           } catch (UnsupportedEncodingException e) {

                   e.printStackTrace();

           } catch (IllegalBlockSizeException e) {

                   e.printStackTrace();

           } catch (BadPaddingException e) {

                   e.printStackTrace();

           }

           return null;

   }

   

   

   

   /**解密

    * @param content  待解密内容

    * @param password 解密密钥

    * @return

    */

   public static byte[] decrypt(byte[] content, String password) {

           try {

                    KeyGenerator kgen = KeyGenerator.getInstance("AES");

                    //kgen.init(128, new SecureRandom(password.getBytes()));

                    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );  

                    secureRandom.setSeed(password.getBytes());  

                    kgen.init(128,secureRandom); 

                    

                    

                    

                    

                    SecretKey secretKey = kgen.generateKey();

                    byte[] enCodeFormat = secretKey.getEncoded();

                    SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");            

                    Cipher cipher = Cipher.getInstance("AES");// 创建密码器

                   cipher.init(Cipher.DECRYPT_MODE, key);// 初始化

                   byte[] result = cipher.doFinal(content);

                   return result; // 加密

           } catch (NoSuchAlgorithmException e) {

                   e.printStackTrace();

           } catch (NoSuchPaddingException e) {

                   e.printStackTrace();

           } catch (InvalidKeyException e) {

                   e.printStackTrace();

           } catch (IllegalBlockSizeException e) {

                   e.printStackTrace();

           } catch (BadPaddingException e) {

                   e.printStackTrace();

           }

           return null;

   }

   

   

   

   /**将二进制转换成16进制

    * @param buf

    * @return

    */

   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

    */

   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;

   }   

}

 

posted on 2015-04-01 11:18  wzyxidian  阅读(1258)  评论(0编辑  收藏  举报

导航