package com.iplatform.core.util;
|
|
import com.walker.infrastructure.utils.Base64;
|
import com.walker.infrastructure.utils.StringUtils;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import javax.crypto.BadPaddingException;
|
import javax.crypto.Cipher;
|
import javax.crypto.IllegalBlockSizeException;
|
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.SecretKey;
|
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.SecretKeySpec;
|
import java.io.UnsupportedEncodingException;
|
import java.nio.charset.StandardCharsets;
|
import java.security.AlgorithmParameters;
|
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidKeyException;
|
import java.security.Key;
|
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchProviderException;
|
import java.security.Security;
|
import java.util.Arrays;
|
|
/**
|
* AES对称加密、解密工具。
|
* @author 时克英
|
* @date 2023-06-15
|
*/
|
public class AESUtils {
|
|
private static final String AES_ALGORITHM = "AES";
|
|
private static final String UTF8 = StandardCharsets.UTF_8.name();
|
|
// 微信解密手机号使用,2023-09-15
|
// static {
|
// Security.addProvider(new BouncyCastleProvider());
|
// }
|
|
/* AES加密 String */
|
public static String encryptStrAES(String text, String key){
|
if(!StringUtils.hasLength(text)){
|
throw new IllegalStateException("encode text should not be null or empty.");
|
}
|
byte[] encodeBytes = encryptByteAES(text.getBytes(StandardCharsets.UTF_8), key);
|
// return Base64.encodeBase64String(encodeBytes);
|
return new String(Base64.encodeBase64(encodeBytes));
|
}
|
|
/* AES解密 String*/
|
public static String decryptStrAES(String text, String key){
|
if(!StringUtils.hasLength(text)){
|
throw new IllegalStateException("decode text should not be null or empty.");
|
}
|
byte[] decoded = Base64.decode(text.getBytes(StandardCharsets.UTF_8));
|
// byte[] decodeBytes = decryptByteAES(Base64.decodeBase64(text.getBytes(StandardCharsets.UTF_8)), key);
|
byte[] decodeBytes = decryptByteAES(decoded, key);
|
return new String(decodeBytes, StandardCharsets.UTF_8);
|
}
|
|
/* AES加密 originalBytes */
|
public static byte[] encryptByteAES(byte[] originalBytes, String key){
|
if(originalBytes == null || originalBytes.length == 0){
|
throw new IllegalStateException("encode originalBytes should not be empty.");
|
}
|
if(!StringUtils.hasLength(key)){
|
throw new IllegalStateException("key :" + key + ", encode key should not be null or empty.");
|
}
|
Cipher cipher = getAESCipher(key, Cipher.ENCRYPT_MODE);
|
byte[] encodeBytes = null;
|
try {
|
encodeBytes = cipher.doFinal(originalBytes);
|
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
throw new IllegalStateException(e.getClass().getName()+": encode byte fail. "+e.getMessage());
|
}
|
return encodeBytes;
|
}
|
|
/* AES解密 encryptedBytes */
|
public static byte[] decryptByteAES(byte[] encryptedBytes, String key){
|
if(encryptedBytes == null || encryptedBytes.length == 0){
|
throw new IllegalStateException("decode encryptedBytes should not be empty.");
|
}
|
if(!StringUtils.hasLength(key)){
|
throw new IllegalStateException("key :" + key + ", decode key should not be null or empty.");
|
}
|
Cipher cipher = getAESCipher(key, Cipher.DECRYPT_MODE);
|
byte[] decodeBytes = null;
|
try {
|
decodeBytes = cipher.doFinal(encryptedBytes);
|
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
throw new IllegalStateException(e.getClass().getName()+": decode byte fail. "+e.getMessage());
|
}
|
return decodeBytes;
|
}
|
|
public static Cipher getAESCipher(String key, int mode){
|
if(!StringUtils.hasLength(key)){
|
throw new IllegalStateException("key :" + key + ", should not be null or empty.");
|
}
|
Cipher cipher = null;
|
SecretKey secretKey;
|
try {
|
cipher = Cipher.getInstance(AES_ALGORITHM);
|
byte[] keyBytes = key.getBytes(UTF8);
|
secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
|
cipher.init(mode, secretKey);
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
throw new IllegalStateException(e.getClass().getName()+": get cipher instance wrong. "+e.getMessage());
|
} catch (UnsupportedEncodingException u){
|
throw new IllegalStateException(u.getClass().getName()+": key transfer bytes fail. "+u.getMessage());
|
} catch (InvalidKeyException i) {
|
throw new IllegalStateException(i.getClass().getName()+": key is invalid. "+i.getMessage());
|
}
|
return cipher;
|
}
|
|
/**
|
* AES解密,目前微信解密授权手机号使用。
|
*
|
* @param content
|
* 密文
|
* @return
|
* @throws InvalidAlgorithmParameterException
|
* @throws NoSuchProviderException
|
* @date 2023-09-15
|
*/
|
public static final byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
|
initialize();
|
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
|
// int base = 16;
|
// if (ivByte.length % base != 0) {
|
// int groups = ivByte.length / base + (ivByte.length % base != 0 ? 1 : 0);
|
// byte[] temp = new byte[groups * base];
|
// Arrays.fill(temp, (byte) 0);
|
// System.arraycopy(ivByte, 0, temp, 0, ivByte.length);
|
// ivByte = temp;
|
// }
|
try {
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
|
Key sKeySpec = new SecretKeySpec(keyByte, AES_ALGORITHM);
|
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
|
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();
|
} catch (NoSuchProviderException e) {
|
e.printStackTrace();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
// 生成iv
|
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
|
AlgorithmParameters params = AlgorithmParameters.getInstance(AES_ALGORITHM);
|
params.init(new IvParameterSpec(iv));
|
return params;
|
}
|
|
public static void initialize() {
|
if (initialized)
|
return;
|
Security.addProvider(new BouncyCastleProvider());
|
initialized = true;
|
}
|
|
public static boolean initialized = false;
|
|
public static final String KEY_16 = "954327510putvwmz";
|
// public static final String KEY_8 = "95432puz";
|
|
public static void main(String[] args) {
|
// String msg = "商户号=adf0099ogglk11wweedcvfg";
|
// System.out.println("AES秘钥长度只能为16、24、32:"+KEY_16.getBytes(StandardCharsets.UTF_8).length);
|
// String s = encryptStrAES(msg, KEY_16);
|
// System.out.println("加密后:"+s);
|
// String s1 = decryptStrAES(s, KEY_16);
|
// System.out.println("解密后:"+s1);
|
String encrypt = "epFJjFcG1VY/3NrhhPBKvA==";
|
System.out.println("解密数据:" + AESUtils.decryptStrAES(encrypt, KEY_16));
|
}
|
}
|