[feat] 增加AES加解密
This commit is contained in:
parent
9731faf9f8
commit
ea13dea70d
|
@ -5,7 +5,7 @@ yexuejc-base 更新记录
|
|||
**branch:** jre8 <br/>
|
||||
**update:** <br/>
|
||||
1. [FileUtil.java](src/main/java/com/yexuejc/base/util/FileUtil.java)增加读取大文件自定义方法和单纯读取方法
|
||||
2.
|
||||
2. 增加AES加解密: [com.yexuejc.base.encrypt.AES](src/main/java/com/yexuejc/base/encrypt/AES.java)
|
||||
---
|
||||
|
||||
#### version :1.5.2-jre8
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
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/ISO10126Padding 32 16
|
||||
AES_CBC_ISO10126Padding("AES/CBC/ISO10126Padding"),
|
||||
//AES/CFB/NoPadding 16 原始数据长度
|
||||
AES_CFB_NoPadding("AES/CFB/NoPadding"),
|
||||
//AES/CFB/PKCS5Padding 32 16
|
||||
AES_CFB_PKCS5Padding("AES/CFB/PKCS5Padding"),
|
||||
//AES/CFB/ISO10126Padding 32 16
|
||||
AES_CFB_ISO10126Padding("AES/CFB/ISO10126Padding"),
|
||||
//AES/ECB/NoPadding 16 不支持
|
||||
AES_ECB_NoPadding("AES/ECB/NoPadding"),
|
||||
//AES/ECB/PKCS5Padding 32 16
|
||||
AES_ECB_PKCS5Padding("AES/ECB/PKCS5Padding"),
|
||||
//AES/ECB/ISO10126Padding 32 16
|
||||
AES_ECB_ISO10126Padding("AES/ECB/ISO10126Padding"),
|
||||
//AES/OFB/NoPadding 16 原始数据长度
|
||||
AES_OFB_NoPadding("AES/OFB/NoPadding"),
|
||||
//AES/OFB/PKCS5Padding 32 16
|
||||
AES_OFB_PKCS5Padding("AES/OFB/PKCS5Padding"),
|
||||
//AES/OFB/ISO10126Padding 32 16
|
||||
AES_OFB_ISO10126Padding("AES/OFB/ISO10126Padding"),
|
||||
//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");
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.yexuejc.base.encrypt;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
|
||||
public class AESTest {
|
||||
|
||||
@Test
|
||||
public void testEncrypt() throws Exception {
|
||||
String data = "Hello World!";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String encrypted = aes.encrypt(data);
|
||||
assertNotNull(encrypted);
|
||||
assertFalse(encrypted.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecrypt() throws Exception {
|
||||
String data = "SGVsbG8gV29ybGQh";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_CBC_PKCS5Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String decrypted = aes.decrypt(data);
|
||||
assertNotNull(decrypted);
|
||||
assertFalse(decrypted.isEmpty());
|
||||
assertEquals("Hello World!", decrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncryptAndDecrypt() throws Exception {
|
||||
String data = "张三";
|
||||
AES aes = AES.builder()
|
||||
.setAlgorithm(AES.ALGORITHM.AES_OFB_ISO10126Padding)
|
||||
.setKey("hj7x89H$yuBI0456")
|
||||
.setIv("NIfb&95GUY86Gfgh")
|
||||
.setCharset(StandardCharsets.UTF_8);
|
||||
String encrypt = aes.encrypt(data);
|
||||
System.out.println("加密:" + encrypt);
|
||||
String decrypt = aes.decrypt(encrypt);
|
||||
System.out.println("解密:" + decrypt);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue