1. 程式人生 > >JAVA 實現AES加密的兩種方法

JAVA 實現AES加密的兩種方法

寫在前面的話:
    1.建議加密後將密文轉為16進位制的字串(便於觀看)。

    2.以下的兩種加密的方法金鑰不限定長度。

[java] view plain copy print?
  1. /** 
  2.  *AES加密解密工具類 
  3.  *@author M-Y 
  4.  */  
  5. public class AESUtil {  
  6.       private static final Logger logger = Logger.getLogger(AESUtil.class);  
  7.       private static final String defaultCharset = "UTF-8";  
  8.       private static
     final String KEY_AES = "AES";  
  9.       private static final String KEY = "123456";  
  10.     /** 
  11.      * 加密 
  12.      * 
  13.      * @param data 需要加密的內容 
  14.      * @param key 加密密碼 
  15.      * @return 
  16.      */  
  17.     public static String encrypt(String data, String key) {  
  18.         return doAES(data, key, Cipher.ENCRYPT_MODE);  
  19.     }  
  20.     /** 
  21.      * 解密 
  22.      * 
  23.      * @param data 待解密內容 
  24.      * @param key 解密金鑰 
  25.      * @return 
  26.      */  
  27.     public static String decrypt(String data, String key) {  
  28.         return doAES(data, key, Cipher.DECRYPT_MODE);  
  29.     }  
  30.     /** 
  31.      * 加解密 
  32.      * 
  33.      * @param data 待處理資料 
  34.      * @param password  金鑰 
  35.      * @param mode 加解密mode
     
  36.      * @return 
  37.      */  
  38.     private static String doAES(String data, String key, int mode) {  
  39.         try {  
  40.             if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {  
  41.                 return null;  
  42.             }  
  43.             //判斷是加密還是解密  
  44.             boolean encrypt = mode == Cipher.ENCRYPT_MODE;  
  45.             byte[] content;  
  46.             //true 加密內容 false 解密內容  
  47.             if (encrypt) {  
  48.                 content = data.getBytes(defaultCharset);  
  49.             } else {  
  50.                 content = parseHexStr2Byte(data);  
  51.             }  
  52.             //1.構造金鑰生成器,指定為AES演算法,不區分大小寫  
  53.             KeyGenerator kgen = KeyGenerator.getInstance(KEY_AES);  
  54.             //2.根據ecnodeRules規則初始化金鑰生成器  
  55.             //生成一個128位的隨機源,根據傳入的位元組陣列  
  56.             kgen.init(128new SecureRandom(key.getBytes()));  
  57.             //3.產生原始對稱金鑰  
  58.             SecretKey secretKey = kgen.generateKey();  
  59.             //4.獲得原始對稱金鑰的位元組陣列  
  60.             byte[] enCodeFormat = secretKey.getEncoded();  
  61.             //5.根據位元組陣列生成AES金鑰  
  62.             SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, KEY_AES);  
  63.             //6.根據指定演算法AES自成密碼器  
  64.             Cipher cipher = Cipher.getInstance(KEY_AES);// 建立密碼器  
  65.             //7.初始化密碼器,第一個引數為加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二個引數為使用的KEY  
  66.             cipher.init(mode, keySpec);// 初始化  
  67.             byte[] result = cipher.doFinal(content);  
  68.             if (encrypt) {  
  69.                 //將二進位制轉換成16進位制  
  70.                 return parseByte2HexStr(result);  
  71.             } else {  
  72.                 return new String(result, defaultCharset);  
  73.             }  
  74.         } catch (Exception e) {  
  75.             logger.error("AES 密文處理異常", e);  
  76.         }  
  77.         return null;  
  78.     }  
  79.     /** 
  80.      * 將二進位制轉換成16進位制 
  81.      * 
  82.      * @param buf 
  83.      * @return 
  84.      */  
  85.     public static String parseByte2HexStr(byte buf[]) {  
  86.         StringBuilder sb = new StringBuilder();  
  87.         for (int i = 0; i < buf.length; i++) {  
  88.             String hex = Integer.toHexString(buf[i] & 0xFF);  
  89.             if (hex.length() == 1) {  
  90.                 hex = '0' + hex;  
  91.             }  
  92.             sb.append(hex.toUpperCase());  
  93.         }  
  94.         return sb.toString();  
  95.     }  
  96.     /** 
  97.      * 將16進位制轉換為二進位制 
  98.      * 
  99.      * @param hexStr 
  100.      * @return 
  101.      */  
  102.     public static byte[] parseHexStr2Byte(String hexStr) {  
  103.         if (hexStr.length() < 1) {  
  104.             return null;  
  105.         }  
  106.         byte[] result = new byte[hexStr.length() / 2];  
  107.         for (int i = 0; i < hexStr.length() / 2; i++) {  
  108.             int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);  
  109.             int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);  
  110.             result[i] = (byte) (high * 16 + low);  
  111.         }  
  112.         return result;  
  113.     }  
  114.     public static void main(String[] args) throws Exception {    
  115.         String content = "{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}";    
  116.         System.out.println("加密前:" + content);    
  117.         System.out.println("加密金鑰和解密金鑰:" + KEY);    
  118.         String encrypt = encrypt(content, KEY);    
  119.         System.out.println("加密後:" + encrypt);    
  120.         String decrypt = decrypt(encrypt, KEY);    
  121.         System.out.println("解密後:" + decrypt);    
  122.     }    
  123. }  
/**
 *AES加密解密工具類
 *@author M-Y
 */
public class AESUtil {
      private static final Logger logger = Logger.getLogger(AESUtil.class);
      private static final String defaultCharset = "UTF-8";
      private static final String KEY_AES = "AES";
      private static final String KEY = "123456";
    /**
     * 加密
     *
     * @param data 需要加密的內容
     * @param key 加密密碼
     * @return
     */
    public static String encrypt(String data, String key) {
        return doAES(data, key, Cipher.ENCRYPT_MODE);
    }

    /**
     * 解密
     *
     * @param data 待解密內容
     * @param key 解密金鑰
     * @return
     */
    public static String decrypt(String data, String key) {
        return doAES(data, key, Cipher.DECRYPT_MODE);
    }

    /**
     * 加解密
     *
     * @param data 待處理資料
     * @param password  金鑰
     * @param mode 加解密mode
     * @return
     */
    private static String doAES(String data, String key, int mode) {
        try {
            if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {
                return null;
            }
            //判斷是加密還是解密
            boolean encrypt = mode == Cipher.ENCRYPT_MODE;
            byte[] content;
            //true 加密內容 false 解密內容
            if (encrypt) {
                content = data.getBytes(defaultCharset);
            } else {
                content = parseHexStr2Byte(data);
            }
            //1.構造金鑰生成器,指定為AES演算法,不區分大小寫
            KeyGenerator kgen = KeyGenerator.getInstance(KEY_AES);
            //2.根據ecnodeRules規則初始化金鑰生成器
            //生成一個128位的隨機源,根據傳入的位元組陣列
            kgen.init(128, new SecureRandom(key.getBytes()));
            //3.產生原始對稱金鑰
            SecretKey secretKey = kgen.generateKey();
            //4.獲得原始對稱金鑰的位元組陣列
            byte[] enCodeFormat = secretKey.getEncoded();
            //5.根據位元組陣列生成AES金鑰
            SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, KEY_AES);
            //6.根據指定演算法AES自成密碼器
            Cipher cipher = Cipher.getInstance(KEY_AES);// 建立密碼器
            //7.初始化密碼器,第一個引數為加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二個引數為使用的KEY
            cipher.init(mode, keySpec);// 初始化
            byte[] result = cipher.doFinal(content);
            if (encrypt) {
                //將二進位制轉換成16進位制
                return parseByte2HexStr(result);
            } else {
                return new String(result, defaultCharset);
            }
        } catch (Exception e) {
            logger.error("AES 密文處理異常", e);
        }
        return null;
    }
    /**
     * 將二進位制轉換成16進位制
     *
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuilder sb = new StringBuilder();
        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 main(String[] args) throws Exception {  
        String content = "{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}";  
        System.out.println("加密前:" + content);  
        System.out.println("加密金鑰和解密金鑰:" + KEY);  
        String encrypt = encrypt(content, KEY);  
        System.out.println("加密後:" + encrypt);  
        String decrypt = decrypt(encrypt, KEY);  
        System.out.println("解密後:" + decrypt);  
    }  
}
輸出結果:[java] view plain copy print?
  1. 加密前:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}  
  2. 加密金鑰和解密金鑰:123456  
  3. 加密後:2A3D75862E69BF61DFAD94017E930227A715C8E533AA1A12361D6BE6E190EC5EE77AA66CAC8005A643BFB26134EE60398C30104B1F7FB3CC6B78795368A86D8215B88A5C80D9C2E4936EEEB0DECA7A88  
  4. 解密後:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}  
加密前:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}
加密金鑰和解密金鑰:123456
加密後:2A3D75862E69BF61DFAD94017E930227A715C8E533AA1A12361D6BE6E190EC5EE77AA66CAC8005A643BFB26134EE60398C30104B1F7FB3CC6B78795368A86D8215B88A5C80D9C2E4936EEEB0DECA7A88
解密後:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}
方法二:替換AESUtil 類中的doAES方法並加上以下成員 [java] view plain copy print?
  1. private static final String KEY_MD5 = "MD5";  
  2. private static MessageDigest md5Digest;  
  3. static {  
  4.     try {  
  5.         md5Digest = MessageDigest.getInstance(KEY_MD5);  
  6.     } catch (NoSuchAlgorithmException e) {  
  7.         //  
  8.     }  
  9. }  
    private static final String KEY_MD5 = "MD5";
    private static MessageDigest md5Digest;

    static {
        try {
            md5Digest = MessageDigest.getInstance(KEY_MD5);
        } catch (NoSuchAlgorithmException e) {
            //
        }
    }
doAES方法: [java] view plain copy print?
  1. /** 
  2.      * 加解密 
  3.      * 
  4.      * @param data 
  5.      * @param key 
  6.      * @param mode 
  7.      * @return 
  8.      */  
  9.     private static String doAES(String data, String key, int mode) {  
  10.         try {  
  11.             if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {  
  12.                 return null;  
  13.             }  
  14.             boolean encrypt = mode == Cipher.ENCRYPT_MODE;  
  15.             byte[] content;  
  16.             //true 加密內容 false 解密內容  
  17.             if (encrypt) {  
  18.                 content = data.getBytes(defaultCharset);  
  19.             } else {  
  20.                  content = parseHexStr2Byte(data);  
  21.             }  
  22.             SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset)), KEY_AES);//構造一個金鑰  
  23.             Cipher cipher = Cipher.getInstance(KEY_AES);// 建立密碼器  
  24.             cipher.init(mode, keySpec);// 初始化  
  25.             byte[] result = cipher.doFinal(content);//加密或解密  
  26.             if (encrypt) {  
  27.                 return parseByte2HexStr(result);  
  28.             } else {  
  29.                 return new String(result, defaultCharset);  
  30.             }  
  31.         } catch (Exception e) {  
  32.             logger.error("AES 密文處理異常", e);  
  33.         }  
  34.         return null;  
  35.     }  

相關推薦

Java實現websocket 的方法

一.WebSocket簡單介紹  隨著網際網路的發展,傳統的HTTP協議已經很難滿足Web應用日益複雜的需求了。近年來,隨著HTML5的誕生,WebSocket協議被提出,它實現了瀏覽器與伺服器的全雙工通訊,擴充套件了瀏覽器與服務端的通訊功能,使服務端也能主動向客戶端傳送資料。  我們知道,傳統的HTTP協議

JAVA 實現AES加密方法

寫在前面的話:    1.建議加密後將密文轉為16進位制的字串(便於觀看)。    2.以下的兩種加密的方法金鑰不限定長度。[java] view plain copy print?/**  *AES加密解密工具類  *@author M-Y  */  public clas

Java實現AES加密(轉)

密鑰 工具 mex 嚴格 keys 生產 ner for 創建 一)什麽是AES? 高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),是一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。 那麽為什麽

java快排(方法

span ast [] ati pub 方法 color 整體 blog 快排是最基礎的排序算法之一,今天來回顧一下。 public class QuickSort { public static void quickSort(int[] ar

Python實現獎金計算方法的比較

position class pla nbsp font fault and dem 100萬 應發獎金計算 簡述:企業發放的獎金根據利潤提成。利潤(profit)低於或等於10萬元時,獎金可提10%; 利潤高於10萬元,低於20萬元時,低於10萬元的部分按1

java String轉Long方法區別

基本數據 ring oat 兩種 基本 ava ger parse 兩種方法 第一種:包裝類型:Byte,Integer,Short,Long,Boolean,Character,Float,Double等8種 Long.valueOf("String")返回Long包裝

java 產生隨機數的方法

一、利用Math.random()方法。 需要生成一個0到99之內的隨機數,通過如下語句就可以實現: i=1+(int)(Math.Random()*100)。 其中(int)(Math.Random()*99)產生0到99的整數型隨機數。然後再加上1就是產生1到100之間的隨機整數。

java實現二分查詢-方式

二分查詢是一種查詢效率非常高的查詢演算法。又稱折半查詢。 起初在資料結構中學習遞迴時實現二分查詢,實際上不用遞迴也可以實現,畢竟遞迴是需要開闢額外的空間的來輔助查詢。本文就介紹兩種方法 二分查詢演算法思想 有序的序列,每次都是以序列的中間位置的數來與待查詢的關鍵字進行比

Java實現AES加密和解密

/** * @param content * @return String * @Description:解密流程: * 1.同加密1-4步 * 2.將加密後的字串反紡成byte[]陣列 * 3.將加密內容解密 */ public stati

Java實現AES加密

一、什麼是AES? AES:Advanced Encrypt Standard 高階加密標準。使用AES是為了代替原先的DES,現如今已被廣泛使用。 相較於DES,使用56位祕鑰,比較容易被破解。AES可以使用128、192和256位祕鑰,並且使用128位分組加密和解密資

java實現AES加密解密

package com.utils; import org.apache.tomcat.util.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpe

Java實現AES加密,異常java.security.InvalidKeyException: Illegal key size 的解決

sta extension ons jdk mit jar文件 目錄 jdk7 ase Java實現AES加密,拋出異常如下:java.security.InvalidKeyException: Illegal key size 代碼參考 http://my.oschi

vtk序列切片影象實現翻轉的方法

由於vtk、itk顯示影象時y軸相反,需要做一次翻轉,這裡介紹兩種方法對於序列影象實現翻轉。1)vtkImageFlip類vtkSmartPointer<vtkImageFlip>flip = vtkSmartPointer<vtkImageFlip>

Java實現生產者消費者模式的方法

1、 利用 Object的 wait/notify,和非阻塞佇列實現 import java.util.PriorityQueue; public class Test{ private int size=10; private PriorityQueue&

DES加密 java與.net可以相互加密解密方法

DES加密 java與.net可以相互加密解密兩種方法 https://www.cnblogs.com/DrWang/archive/2011/03/30/2000124.html   sun.misc.BASE64Decoder.jar最新 https://download.csdn.ne

Java實現變數交換的方法

方法一:引入第三方變數 public class ChangeVar{ public static void main(String[] args){ //交換變數 int a = 1; int b = 2; int c= a; //1 a = b;//2 b

Java——用方法實現字串逆序

package com.zth; public class Test{ public static String fun1(String str){ //方法一 將字串轉換為字元陣列 char[] arr = str.toCharA

Java動態代理的實現方法

AOP的攔截功能是由java中的動態代理來實現的。說白了,就是在目標類的基礎上增加切面邏輯,生成增強的目標類(該切面邏輯或者在目標類函式執行之前,或者目標類函式執行之後,或者在目標類函式丟擲異常時候執行。不同的切入時機對應不同的Interceptor的種類,如BeforeAd

Java實現記憶體可見性的方法比較:synchronized 和 Volatile以及涉及到鎖的剖析

這篇文中講述了通過synchronized和 volatile 變數實現記憶體可見性的方法,這裡比較下二者的區別。 * volatile 變數是一種稍弱的同步機制在訪問 volatile 變數時不會執行加鎖操作,因此也就不會使執行執行緒阻塞,因此 vola

Java併發:建立執行緒的方法:繼承Thread類和實現Runnable介面(一)

【1】瞭解程序與執行緒的概念 程序是一個程式在其自身的地址空間中執行一次活動,是資源申請、排程和獨立執行的單位。 執行緒是程序中的一個單一的連續控制流程,一個程序可以包含一個或多個執行緒。 如果要在