AES算法,不管是性能还是安全性都比较高,今天项目里用得到,就顺手写了一个Utils,感觉还不错,就贴出来,方便以后使用
import org.testng.annotations.Test;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class AESUtil {
@Test
public void test() {
Key key = AESUtil.init("dist@2019");
String encrypt = AESUtil.encrypt("uuid:1234565,date:2019.10.10", key);
System.out.println(encrypt);
System.out.println(decrypt(encrypt, key));
}
/**
* 初始化秘钥,初始化后,请持久化保存,减少初始化次数
*
* @param password 加密或解密秘钥
* @return
*/
public static Key init(String password) {
try {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
keygen.init(128,secureRandom);
byte[] enCodeFormat = keygen.generateKey().getEncoded();
return new SecretKeySpec(enCodeFormat, "AES");
return new SecretKeySpec(enCodeFormat, "AES");
// 创建密码器
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密操作需要先执行init(String password)
* @param content 解密内容
* @param key init(String password)的返回参数
* @return
*/
public static String decrypt(String content, Key key) {
try {
Cipher cipher = getCipher(key, false);
byte[] result = cipher.doFinal(Base64Utils.decoder(content));
return new String(result);
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
/**
* 加密操作
* @param content 需要加密的内容
* @param key init(String password)的返回参数
* @return
*/
public static String encrypt(String content, Key key) {
try {
Cipher cipher = getCipher(key, true);
byte[] result = cipher.doFinal(content.getBytes());
String data = Base64Utils.encoderToString(result);
return data;
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
/**
* 构造Cipher器,用于加密解密操作,该方法为内部方法,不需要调用
* @param key init(String password)的返回参数
* @param isEncrypt 是否是加密内容,true则为加密,falseWie解密
* @return
*/
private static Cipher getCipher(Key key, boolean isEncrypt) {
try {
Cipher cipher = Cipher.getInstance("AES");
if (isEncrypt) {
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher;
}
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
}
多次试验发现,耗时最多的代码是创建Cipher 的过程,所以我们想办法将他保存起来
package com.novel.platform.tool.sys.bean;
import com.novel.platform.tool.utils.Base64Utils;
import org.testng.annotations.Test;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* @author weihuibin 2019/9/20
*/
public class AESBean {
private Cipher encryptCipher;
private Cipher decryptCipher;
private AESBean(String password){
Key key = initKey(password);
decryptCipher=initDecrypt(key);
encryptCipher=initEncrypt(key);
}
public static AESBean getInstance(String password){
return new AESBean(password);
}
@Test
public void test() throws InterruptedException {
String password = "dist@2019";
AESBean aesBean = AESBean.getInstance("dist@2019");
for (int i = 0; i < 1000; i++) {
new Thread(() -> {
for (int j = 0; j < 100; j++) {
String encrypt = aesBean.encrypt("uuid:1234565,date:2019.10.10");
System.out.println(aesBean.decrypt(encrypt));
}
}).start();
}
Thread.sleep(10000);
}
/**
* 初始化秘钥,初始化后,请持久化保存,减少初始化次数
*
* @param password 加密或解密秘钥
* @return
*/
private Key initKey(String password) {
try {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
keygen.init(128,secureRandom);
byte[] enCodeFormat = keygen.generateKey().getEncoded();
return new SecretKeySpec(enCodeFormat, "AES");
// 创建密码器
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private Cipher initEncrypt(Key key) {
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,key);
return cipher;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
private Cipher initDecrypt(Key key) {
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,key);
return cipher;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密操作需要先执行init(String password)
* @param content 解密内容
* @return
*/
public String decrypt(String content) {
try {
byte[] result = decryptCipher.doFinal(Base64Utils.decoder(content));
return new String(result);
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
/**
* 加密操作
* @param content 需要加密的内容
* @return
*/
public String encrypt(String content) {
try {
byte[] result = encryptCipher.doFinal(content.getBytes());
String data = Base64Utils.encoderToString(result);
return data;
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return "";
}
/**
* 构造Cipher器,用于加密解密操作,该方法为内部方法,不需要调用
* @param key init(String password)的返回参数
* @param isEncrypt 是否是加密内容,true则为加密,falseWie解密
* @return
*/
private Cipher getCipher(Key key, boolean isEncrypt) {
try {
Cipher cipher = Cipher.getInstance("AES");
if (isEncrypt) {
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher;
}
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
}