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); } }