zoukankan      html  css  js  c++  java
  • 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.          try {           

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

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

    5.                 return _generator.generateKey();  

    6.         }  catch (Exception e) {  

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

    8.         }  

    9.       }   

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

    view plaincopy to clipboardprint?

    1. public static SecretKey getKey(String strKey) {  

    2.        try {           

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

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

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

    6.           _generator.init(128,secureRandom);  

    7.               return _generator.generateKey();  

    8.       }  catch (Exception e) {  

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

    10.       }  

    11.     }   

    原因分析

    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;

       }   

    }

  • 相关阅读:
    终端程序开机后自动运行
    SQLite 3 使用前要知道的
    JS 框架 :后台系统完整的解决方案
    JS 继承:extend、mixin 和 plugin(三)
    JS 控件事件
    JS 控件 jQuery扩展函数
    Js 控件编写 继承:extend、mixin和plugin(一)
    关于js new Date() 出现NaN 的分析
    js Dialog 实践
    JS控件 生命周期
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/4383363.html
Copyright © 2011-2022 走看看