zoukankan      html  css  js  c++  java
  • AES加密【转】

    .

     

    此时就一定要使用如下代码步骤 :

    1.SecureRandom的key定下来.

    SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;

    该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同.

    public static SecretKey getKey(String strKey) {  
           try {           
              KeyGenerator _generator = KeyGenerator.getInstance( "AES" );  
               SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );  
              secureRandom.setSeed(strKey.getBytes());  
              _generator.init(128,secureRandom);  
                  return _generator.generateKey();  
          }  catch (Exception e) {  
               throw new RuntimeException( " 初始化密钥出现异常 " );  
          }  
        }

    2. 16进制转换为2进制 互转

    * 因为加密后的byte数组是不能强制转换成字符串的,
    * 换言之:字符串和byte数组在这种情况下不是互逆的;
    * 要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示

    3. BASE64加解密 

     这个原因和2有点类似,仿佛有点多余,也许能省下这一步.

     4. 如果不这么做

    windows上加解密正常,linux上加密正常,解密时发生如下异常:
     
    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) 

    而我自己遇上的情况比这更糟,同样的windows环境,

    用apache的httppost发送加密报文在tomcat服务端进行解密就会报以上异常,

    但是用java原生态的UrlConnection发送加密报文在tomcat服务端进行解密一切正常.

    可能是apache对发送的流填充模式不同吧@@!

    代码示例

    package com.testdemo.validate.endecrypt;
    import java.io.IOException;  
    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;  
      
    
    
    
    import sun.misc.BASE64Decoder;  
    import sun.misc.BASE64Encoder;  
      
    public class AESTool {  
        private final static String encoding = "UTF-8";   
        /** 
         * AES加密 
         *  
         * @param content 
         * @param password 
         * @return 
         */  
        public static String encryptAES(String content, String password) {  
            byte[] encryptResult = encrypt(content, password);  
            String encryptResultStr = parseByte2HexStr(encryptResult);  
            // BASE64位加密  
            encryptResultStr = encryptBASE64(encryptResultStr);  
            return encryptResultStr;  
        }  
      
        /** 
         * AES解密 
         *  
         * @param encryptResultStr 
         * @param password 
         * @return 
         */  
        public static String decryptAES(String encryptResultStr, String password) {  
            // BASE64位解密  
            String decrpt = decryptBASE64(encryptResultStr);  
            byte[] decryptFrom = parseHexStr2Byte(decrpt);  
            byte[] decryptResult = decrypt(decryptFrom, password);  
            return new String(decryptResult);  
        }  
      
            /** 
         * 加密字符串 
         */  
        public static String encryptBASE64(String str) {  
            BASE64Encoder base64encoder = new BASE64Encoder();  
            String result = str;  
            if (str != null && str.length() > 0) {  
                try {  
                    byte[] encodeByte = str.getBytes(encoding);  
                    result = base64encoder.encode(encodeByte);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
            //base64加密超过一定长度会自动换行 需要去除换行符  
            return result.replaceAll("
    ", "").replaceAll("
    ", "").replaceAll("
    ", "");  
        }  
      
        /** 
         * 解密字符串 
         */  
        public static String decryptBASE64(String str) {  
            BASE64Decoder base64decoder = new BASE64Decoder();  
            try {  
                byte[] encodeByte = base64decoder.decodeBuffer(str);  
                return new String(encodeByte);  
            } catch (IOException e) {  
                e.printStackTrace();  
                return str;  
            }  
        }  
        /**   
         * 加密   
         *    
         * @param content 需要加密的内容   
         * @param password  加密密码   
         * @return   
         */    
        private static byte[] encrypt(String content, String password) {     
                try {                
                        KeyGenerator kgen = KeyGenerator.getInstance("AES");   
                        //防止linux下 随机生成key  
                        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );     
                        secureRandom.setSeed(password.getBytes());     
                        kgen.init(128, secureRandom);  
                        //kgen.init(128, new SecureRandom(password.getBytes()));     
                        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   
         */    
        private static byte[] decrypt(byte[] content, String password) {     
                try {     
                         KeyGenerator kgen = KeyGenerator.getInstance("AES");   
                       //防止linux下 随机生成key  
                         SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );     
                         secureRandom.setSeed(password.getBytes());     
                         kgen.init(128, secureRandom);  
                         //kgen.init(128, new SecureRandom(password.getBytes()));     
                         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;     
        }    
      
      
        public static void test1() {
            String content = "test";
            String password = "12345678";
            // 加密
            System.out.println("加密前:" + content);
            String encryptResult = encryptAES(content, password);
            System.out.println("加密后: "+ encryptResult);
            // 解密
            System.out.println("解密前: "+ encryptResult);
            String decryptResult = decryptAES(encryptResult, password);
            System.out.println("解密后:" + new String(decryptResult));
        }
        
        public static void main(String[] args) {
            test1();
        }
          
    } 

    http://konglx.iteye.com/blog/954085

    http://www.cnblogs.com/freeliver54/archive/2011/10/08/2202136.html   java源码下载  

  • 相关阅读:
    C语言中的复合类型
    C语言中的函数与指针
    C语言中的循环结构与选择结构
    C语言中的运算符
    C语言中的变量
    毕业论文查重网站
    Protocol and Delegate协议和代理
    NSArray与NSMutableArray 数组与可变数组
    UI复习
    NSString方法与NSMutableString方法
  • 原文地址:https://www.cnblogs.com/whatlonelytear/p/5669563.html
Copyright © 2011-2022 走看看