231 lines
7.6 KiB
Java
231 lines
7.6 KiB
Java
package ink.wgink.util;
|
||
|
||
import org.apache.commons.codec.binary.Base64;
|
||
import org.apache.commons.codec.binary.StringUtils;
|
||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||
|
||
import javax.crypto.Cipher;
|
||
import javax.crypto.KeyGenerator;
|
||
import javax.crypto.SecretKey;
|
||
import javax.crypto.spec.IvParameterSpec;
|
||
import javax.crypto.spec.SecretKeySpec;
|
||
import java.security.SecureRandom;
|
||
import java.security.Security;
|
||
|
||
public class AesUtil {
|
||
|
||
private static final String IV_STRING = "16-Bytes--String";
|
||
/**
|
||
* PKCS#7
|
||
*/
|
||
public static final String PKCS_7 = "PKCS7Padding";
|
||
/**
|
||
* PKCS#5
|
||
*/
|
||
public static final String PKCS_5 = "PKCS5Padding";
|
||
|
||
/**
|
||
* AES加密
|
||
*
|
||
* @param encodeRule
|
||
* @param content
|
||
* @return
|
||
* @throws Exception
|
||
*/
|
||
public static String aesEncoder(String encodeRule, String content) {
|
||
try {
|
||
// 1.构造秘钥生成器
|
||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||
// 2.根据编码规则构建秘钥生成器
|
||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||
random.setSeed(encodeRule.getBytes());
|
||
keyGenerator.init(128, random);
|
||
// 3.产生堆成秘钥
|
||
SecretKey secretKey = keyGenerator.generateKey();
|
||
// 4.对称秘钥原始数组
|
||
byte[] secretKeyByte = secretKey.getEncoded();
|
||
// 5.生成AES秘钥
|
||
SecretKey key = new SecretKeySpec(secretKeyByte, "AES");
|
||
// 6.初始化密码器
|
||
Cipher cipher = Cipher.getInstance("AES");
|
||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||
// 8.获取加密内容字节数组
|
||
byte[] contentByte = content.getBytes("UTF-8");
|
||
// 9.加密
|
||
return new String(Base64.encodeBase64(cipher.doFinal(contentByte)));
|
||
} catch (Exception e) {
|
||
throw new AesEncodeException(e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* AES解密
|
||
*
|
||
* @param encodeRule
|
||
* @param content
|
||
* @return
|
||
*/
|
||
public static String aesDecoder(String encodeRule, String content) {
|
||
try {
|
||
// 1.构建秘钥生成器
|
||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||
// 2.根据编码规则构建秘钥生成器
|
||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||
random.setSeed(encodeRule.getBytes());
|
||
keyGenerator.init(128, random);
|
||
// 3.生成对称解密秘钥
|
||
SecretKey secretKey = keyGenerator.generateKey();
|
||
// 4.对称秘钥原始数组
|
||
byte[] secretKeyByte = secretKey.getEncoded();
|
||
// 5.生成AES秘钥
|
||
SecretKey key = new SecretKeySpec(secretKeyByte, "AES");
|
||
// 6.初始化密码器
|
||
Cipher cipher = Cipher.getInstance("AES");
|
||
cipher.init(Cipher.DECRYPT_MODE, key);
|
||
// 7.要解密内容的字节数组
|
||
byte[] contentByte = Base64.decodeBase64(content);
|
||
// 8.解密
|
||
return new String(cipher.doFinal(contentByte), "UTF-8");
|
||
} catch (Exception e) {
|
||
throw new AesDecodeException(e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通用aes加密,兼容IOS
|
||
*
|
||
* @param key
|
||
* @param content
|
||
* @return
|
||
*/
|
||
public static String aesCommonEncoder(String key, String content) {
|
||
try {
|
||
byte[] encryptedBytes = aesCommonEncodeDetail(key, content, IV_STRING.getBytes(), PKCS_5);
|
||
return new String(Base64.encodeBase64(encryptedBytes), "UTF-8");
|
||
} catch (Exception e) {
|
||
throw new AesEncodeException(e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通用aes加密,兼容IOS
|
||
*
|
||
* @param key
|
||
* @param content
|
||
* @param paddingType
|
||
* @return
|
||
*/
|
||
public static byte[] aesCommonEncodeDetail(String key, String content, byte[] ivBytes, String paddingType) {
|
||
try {
|
||
byte[] byteContent = content.getBytes("UTF-8");
|
||
byte[] enCodeFormat = key.getBytes();
|
||
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
|
||
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
|
||
if (StringUtils.equals(paddingType, PKCS_7)) {
|
||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||
}
|
||
Cipher cipher = Cipher.getInstance("AES/CBC/" + paddingType);
|
||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
||
return cipher.doFinal(byteContent);
|
||
} catch (Exception e) {
|
||
throw new AesEncodeException(e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* aes通用解密,兼容IOS
|
||
*
|
||
* @param key
|
||
* @param content
|
||
* @return
|
||
* @throws Exception
|
||
*/
|
||
public static String aesCommonDecoder(String key, String content) {
|
||
try {
|
||
byte[] encryptedBytes = Base64.decodeBase64(content);
|
||
byte[] keyBytes = key.getBytes();
|
||
byte[] result = aesCommonDecoderDetail(keyBytes, encryptedBytes, IV_STRING.getBytes(), PKCS_5);
|
||
return new String(result, "UTF-8");
|
||
} catch (Exception e) {
|
||
throw new AesDecodeException(e.getMessage(), e);
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* aes cbc 通用解密
|
||
*
|
||
* @param keyBytes 秘钥字节数组
|
||
* @param encryptedBytes 密文字节数组
|
||
* @param ivBytes 向量字节数组
|
||
* @param paddingType 填充类型
|
||
* @return
|
||
*/
|
||
public static byte[] aesCommonDecoderDetail(byte[] keyBytes, byte[] encryptedBytes, byte[] ivBytes, String paddingType) {
|
||
try {
|
||
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
|
||
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
|
||
Cipher cipher;
|
||
if (StringUtils.equals(paddingType, PKCS_7)) {
|
||
Security.addProvider(new BouncyCastleProvider());
|
||
}
|
||
cipher = Cipher.getInstance("AES/CBC/" + paddingType);
|
||
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
|
||
return cipher.doFinal(encryptedBytes);
|
||
} catch (Exception e) {
|
||
throw new AesDecodeException(e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* AES解密异常
|
||
*/
|
||
public static class AesDecodeException extends RuntimeException {
|
||
|
||
public AesDecodeException() {
|
||
}
|
||
|
||
public AesDecodeException(String message) {
|
||
super(message);
|
||
}
|
||
|
||
public AesDecodeException(String message, Throwable cause) {
|
||
super(message, cause);
|
||
}
|
||
|
||
public AesDecodeException(Throwable cause) {
|
||
super(cause);
|
||
}
|
||
|
||
public AesDecodeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||
super(message, cause, enableSuppression, writableStackTrace);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* AES加密异常
|
||
*/
|
||
public static class AesEncodeException extends RuntimeException {
|
||
|
||
public AesEncodeException() {
|
||
}
|
||
|
||
public AesEncodeException(String message) {
|
||
super(message);
|
||
}
|
||
|
||
public AesEncodeException(String message, Throwable cause) {
|
||
super(message, cause);
|
||
}
|
||
|
||
public AesEncodeException(Throwable cause) {
|
||
super(cause);
|
||
}
|
||
|
||
public AesEncodeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||
super(message, cause, enableSuppression, writableStackTrace);
|
||
}
|
||
}
|
||
|
||
}
|