AES加密解密工具類(推薦使用CBC模式)


  AES加密算法,用於不能明文發送的報文中(比如個人信息中的身份證,手機等重要私密信息),后端加密,前端解密。

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class AESUtils {
    //日志相關
    private static final Logger log = LoggerFactory.getLogger(AESUtils.class);
    //編碼
    private static final String ENCODING = "UTF-8";
    // 算法定義
    private static final String AES_ALGORITHM = "AES";
    // 指定填充方式
    private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";
    private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";
    //偏移量(CBC中使用,增強加密算法強度)
    private static final String IV_SEED = "1234567812345678";

    /**
     * AES加密
     * @param content 待加密內容
     * @param aesKey  密碼
     * @return
     */
    public static String encrypt(String content, String aesKey){
        if(StringUtils.isBlank(content)){
            log.info("AES encrypt: the content is null!");
            return null;
        }
        //判斷秘鑰是否為16位
        if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
            try {
                //對密碼進行編碼
                byte[] bytes = aesKey.getBytes(ENCODING);
                //設置加密算法,生成秘鑰
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/補碼方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //選擇加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                //根據待加密內容生成字節數組
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                //返回base64字符串
                return Base64.encodeBase64String(encrypted);
            } catch (Exception e) {
                log.info("AES encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        }else {
            log.info("AES encrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * 解密
     * @param content 待解密內容
     * @param aesKey  密碼
     * @return
     */
    public static String decrypt(String content, String aesKey){
        if(StringUtils.isBlank(content)){
            log.info("AES decrypt: the content is null!");
            return null;
        }
        //判斷秘鑰是否為16位
        if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
            try {
                //對密碼進行編碼
                byte[] bytes = aesKey.getBytes(ENCODING);
                //設置解密算法,生成秘鑰
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/補碼方式"
                Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                //選擇解密
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);

                //先進行Base64解碼
                byte[] decodeBase64 = Base64.decodeBase64(content);

                //根據待解密內容進行解密
                byte[] decrypted = cipher.doFinal(decodeBase64);
                //將字節數組轉成字符串
                return new String(decrypted, ENCODING);
            } catch (Exception e) {
                log.info("AES decrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        }else {
            log.info("AES decrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * AES_CBC加密
     * @param content 待加密內容
     * @param aesKey  密碼
     * @return
     */
    public static String encryptCBC(String content, String aesKey){
        if(StringUtils.isBlank(content)){
            log.info("AES_CBC encrypt: the content is null!");
            return null;
        }
        //判斷秘鑰是否為16位
        if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
            try {
                //對密碼進行編碼
                byte[] bytes = aesKey.getBytes(ENCODING);
                //設置加密算法,生成秘鑰
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                // "算法/模式/補碼方式"
                Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                //偏移
                IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                //選擇加密
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                //根據待加密內容生成字節數組
                byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                //返回base64字符串
                return Base64.encodeBase64String(encrypted);
            } catch (Exception e) {
                log.info("AES_CBC encrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        }else {
            log.info("AES_CBC encrypt: the aesKey is null or error!");
            return null;
        }
    }

    /**
     * AES_CBC解密
     * @param content 待解密內容
     * @param aesKey  密碼
     * @return
     */
    public static String decryptCBC(String content, String aesKey){
        if(StringUtils.isBlank(content)){
            log.info("AES_CBC decrypt: the content is null!");
            return null;
        }
        //判斷秘鑰是否為16位
        if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
            try {
                //對密碼進行編碼
                byte[] bytes = aesKey.getBytes(ENCODING);
                //設置解密算法,生成秘鑰
                SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                //偏移
                IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                // "算法/模式/補碼方式"
                Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                //選擇解密
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

                //先進行Base64解碼
                byte[] decodeBase64 = Base64.decodeBase64(content);

                //根據待解密內容進行解密
                byte[] decrypted = cipher.doFinal(decodeBase64);
                //將字節數組轉成字符串
                return new String(decrypted, ENCODING);
            } catch (Exception e) {
                log.info("AES_CBC decrypt exception:" + e.getMessage());
                throw new RuntimeException(e);
            }

        }else {
            log.info("AES_CBC decrypt: the aesKey is null or error!");
            return null;
        }
    }

    public static void main(String[] args) {
        String random = RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz1234567890");
        System.out.println("隨機:" + random);
        String aesResult = encrypt("測試AES加密12", random);
        System.out.println("aes加密結果:" + aesResult);

        System.out.println("---------解密---------");
        String decrypt = decrypt(aesResult, random);
        System.out.println("aes解密結果:" + decrypt);


        System.out.println("--------AES_CBC加密解密---------");
        String cbcResult = encryptCBC("測試AES加密12456", random);
        System.out.println("aes_cbc加密結果:" + cbcResult);
        System.out.println("---------解密CBC---------");
        String cbcDecrypt = decryptCBC(cbcResult, random);
        System.out.println("aes解密結果:" + cbcDecrypt);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM