2024-07-04 17:39:45 +08:00

198 lines
7.4 KiB
Java

package com.yexuejc.base.encrypt;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES加解密
*
* @author maxf
* @class-name AES
* @description
* @date 2022/11/11 15:36
*/
public class AES {
public static AES builder() {
return Instace.aes;
}
private static class Instace {
private static AES aes = new AES();
}
public static final String AES_ALGORITHM = "AES";
/**
* 加密模式
*/
public static enum ALGORITHM {
//算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
//AES/CBC/NoPadding 16 不支持
AES_CBC_NoPadding("AES/CBC/NoPadding"),
//AES/CBC/PKCS5Padding 32 16
AES_CBC_PKCS5Padding("AES/CBC/PKCS5Padding"),
//AES/CBC/PKCS7Padding 32 16
AES_CBC_PKCS7Padding("AES/CBC/PKCS7Padding"),
//AES/CBC/ISO10126Padding 32 16
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
//AES/CBC/ZeroPadding 16 16
AES_CBC_ZeroPadding("AES/CBC/ZeroPadding"),
//AES/CFB/NoPadding 16 原始数据长度
AES_CFB_NoPadding("AES/CFB/NoPadding"),
//AES/CFB/PKCS5Padding 16 不支持
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
//AES/CFB/PKCS7Padding 16 不支持
AES_CFB_PKCS7Padding("AES/CFB/PKCS7Padding"),
//AES/CFB/ISO10126Padding 16 不支持
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
//AES/CFB/ZeroPadding 16 不支持
AES_CFB_ZeroPadding("AES/CFB/ZeroPadding"),
//AES/ECB/NoPadding 16 不支持
AES_ECB_NoPadding("AES/ECB/NoPadding"),
//AES/ECB/PKCS5Padding 32 不支持
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
//AES/ECB/PKCS7Padding 32 16
AES_ECB_PKCS7Padding("AES/ECB/PKCS7Padding"),
//AES/ECB/ISO10126Padding 32 16
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
//AES/ECB/ZeroPadding 16 16
AES_ECB_ZeroPadding("AES/ECB/ZeroPadding"),
//AES/OFB/NoPadding 16 原始数据长度
AES_OFB_NoPadding("AES/OFB/NoPadding"),
//AES/OFB/PKCS5Padding 32 16
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
//AES/OFB/PKCS7Padding 32 16
AES_OFB_PKCS7Padding("AES/OFB/PKCS7Padding"),
//AES/OFB/ISO10126Padding 32 16
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
//AES/OFB/ZeroPadding 16 16
AES_OFB_ZeroPadding("AES/OFB/ZeroPadding"),
//AES/PCBC/NoPadding 16 不支持
AES_PCBC_NoPadding("AES/PCBC/NoPadding"),
//AES/PCBC/PKCS5Padding 32 16
AES_PCBC_PKCS5Padding("AES/PCBC/PKCS5Padding"),
//AES/PCBC/ISO10126Padding 32 16
AES_PCBC_ISO10126Padding("AES/PCBC/ISO10126Padding"),
//AES/CTR/NoPadding 16 不支持
AES_CTR_NoPadding("AES/CTR/NoPadding");
public String name;
ALGORITHM(String name) {
this.name = name;
}
}
private ALGORITHM algorithm = ALGORITHM.AES_CBC_NoPadding;
private String key = "hj7x89H$yuBI0456";
private String iv = "NIfb&95GUY86Gfgh";
private Charset charset = StandardCharsets.UTF_8;
/**
* 加密
*
* @param data 明文
* @return 密文
* @Description AES算法加密明文
*/
public String encrypt(String data) throws Exception {
try {
Cipher cipher = Cipher.getInstance(algorithm.name);
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes(charset);
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
IvParameterSpec ivspec = null;
if(!algorithm.name.contains("ECB")){
ivspec = new IvParameterSpec(iv.getBytes(charset));
}
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 解密
*
* @param data 密文
* @return 明文
* @Description AES算法解密密文
*/
public String decrypt(String data) throws Exception {
try {
byte[] encrypted = Base64.getDecoder().decode(data);
Cipher cipher = Cipher.getInstance(algorithm.name);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(charset), AES_ALGORITHM);
IvParameterSpec ivspec = null;
if(!algorithm.name.contains("ECB")){
ivspec = new IvParameterSpec(iv.getBytes(charset));
}
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted);
return new String(original, charset).trim();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//
// public static void main(String[] args) throws Exception {
// String str = " 奥萨蒂 asd8阿斯顿8asd ";
// AES.builder().setAlgorithm(ALGORITHM.AES_CBC_ISO10126Padding);
// AES.builder().setKey("DEsx89H$yuBI0456");
// String encrypt = AES.builder().encrypt(str);
// System.out.println(encrypt);
// String decrypt = AES.builder().decrypt(encrypt);
// System.out.println(">>>" + decrypt + "<<<");
// }
public ALGORITHM getAlgorithm() {
return algorithm;
}
public AES setAlgorithm(ALGORITHM algorithm) {
this.algorithm = algorithm;
return this;
}
public String getKey() {
return key;
}
public AES setKey(String key) {
this.key = key;
return this;
}
public String getIv() {
return iv;
}
public AES setIv(String iv) {
this.iv = iv;
return this;
}
public Charset getCharset() {
return charset;
}
public AES setCharset(Charset charset) {
this.charset = charset;
return this;
}
}