1、JAVA后端代码
import lombok.extern.slf4j.Slf4j;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
/**
* AesUtil
*
* @date 2019/8/14
* @description AES加密工具类
*/
@Slf4j
public class AesUtil {
private static AesUtil instance = null;
private Cipher cipher;
SecretKeySpec key = null;
AlgorithmParameterSpec iv = null;
public static AesUtil getInstance() {
String key = "539777c69fd1d0db113a1256866d69aa";
String iv = "6bb9d4211b236bea79ba84c16107f333";
return getInstance(key, iv);
}
public static AesUtil getInstance(String key, String iv) {
if (instance == null) {
instance = new AesUtil(key, iv);
}
return instance;
}
/**
* 构造器
*
* @param keyStr
* @param ivStr
*/
private AesUtil(String keyStr, String ivStr) {
try {
iv = new IvParameterSpec(packHex(ivStr));
key = new SecretKeySpec(packHex(keyStr), "AES");
// 加解密功能由Cipher组件提供
// 获取Cipher实例AES-128位-有向量 加密模式为CBC,填充模式为PKCS5Padding
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
log.error("AesUtil Constructor NoSuchAlgorithmException", e);
} catch (NoSuchPaddingException e) {
log.error("AesUtil Constructor NoSuchPaddingException", e);
}
}
/**
* 将32bytes的16禁止串压缩成16bytes,充分利用128bits的密钥空间
*
* @param hex
* @return byte[]
*/
public static byte[] packHex(String hex) {
int len = hex.length() >> 1;
byte[] b = new byte[len];
short k = 0;
for (int i = 0, j = 0; i < len; i++, j = i << 1) {
k = Short.parseShort(hex.substring(j, j + 2), 16);
b[i] = (byte) (k & 0xff);
}
return b;
}
/**
* 加密
*
* @param txt 待加密文本字节数组
* @return
*/
public byte[] encrypt(byte[] txt) {
try {
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(txt);
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
log.error("encrypt" + "_" + e.getMessage(), e);
}
return new byte[0];
}
/**
* 加密
*
* @param txt 待加密文本字符串
* @return
*/
public String encrypt(String txt) {
byte[] b = this.encrypt(txt.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(b);
}
/**
* 加密(去除特殊字符'+','/','=')
* @param txt 加密字符
* @return
*/
public String encryptNoSpecialSymbol(String txt) {
byte[] b = this.encrypt(txt.getBytes(StandardCharsets.UTF_8));
return Base64.getUrlEncoder().withoutPadding().encodeToString(b);
}
/**
* 解密(去除特殊字符'+','/','=')
* @param txt
* @return
*/
public String decryptNoSpecialSymbol(String txt) {
byte[] b = txt.getBytes();
b = Base64.getUrlDecoder().decode(b);
b = decrypt(b);
return new String(b, StandardCharsets.UTF_8);
}
/**
* 解密
*
* @param txt 待解密文本字节数组
* @return
*/
public byte[] decrypt(byte[] txt) {
try {
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(txt);
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
log.error("decrypt" + "_" + e.getMessage(), e);
}
return new byte[0];
}
/**
* 解密
*
* @param txt
* @return
*/
public String decrypt(String txt) {
byte[] b = txt.getBytes();
b = Base64.getDecoder().decode(b);
b = decrypt(b);
return new String(b, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
AesUtil aesUtil = AesUtil.getInstance();
String encryptString = aesUtil.encrypt("530302201210302749");
log.info("encryptString:{},size:{}", encryptString, encryptString.length());
String decryptString = aesUtil.decrypt(encryptString);
log.info("decryptString:{}", decryptString);
}
}
2、前端JS代码,引入CryptoJS-3.1.2包components中的aes-min.js
//加密
var key = CryptoJS.enc.Hex.parse("539777c69fd1d0db113a1256866d69aa");
var iv = CryptoJS.enc.Hex.parse("6bb9d4211b236bea79ba84c16107f333");
var srcs = CryptoJS.enc.Utf8.parse("hello world 137 牛");
var enc = CryptoJS.AES.encrypt(srcs, key, {
mode:CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,iv: iv
});
let value = enc.toString();
console.log("encrypt aes:"+value);
//解密
var key = CryptoJS.enc.Hex.parse("539777c69fd1d0db113a1256866d69aa");
var iv = CryptoJS.enc.Hex.parse("6bb9d4211b236bea79ba84c16107f333");
var dec = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Base64.parse(value));
var decrypt = CryptoJS.AES.decrypt(dec,key,{
mode:CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,iv: iv
});
var word = decrypt.toString(CryptoJS.enc.Utf8)
console.log("decrypt aes:"+word);