Java和JavaScript(CryptoJS)的AES互相加解密实现
一、Java 后端
java后端代码采用jdk提供的加解密算法实现(中间穿插了部分其他库的工具类apache-common),异常捕获那块还可以细化!(转载请标明来源!!!!!!!!!!)
1.1 java代码实现
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
/**
* @author 桔梗迷
* @date 2023/10/19 14:35
*/
public class AesUtil {
private static final Log log = LogFactory.getLog(AesUtil.class);
private static final java.util.Base64.Encoder ENCODER = java.util.Base64.getEncoder();
private static final java.util.Base64.Decoder DECODER = java.util.Base64.getDecoder();
/**
* 默认key 16位byte[] [106, -26, -43, -79, -22, 11, -49, 112, 100, -111, -27, -54, 9, 115, 115, 50]
*/
private static final String DEFAULT_KEY = "aubVseoLz3BkkeXKCXNzMg==";
/**
* 默认向量 16位byte[] {25, 101, -116, -100, 98, 100, -125, 126, -57, -26, 3, 107, -45, 79, -34, -19}
*/
public static final String DEFAULT_IV = "GWWMnGJkg37H5gNr00/e7Q==";
/**
* 对称加密
*
* @param plainText 明文
*/
public static String encrypt(String plainText) throws Exception {
return encrypt(plainText, DEFAULT_KEY);
}
/**
* 对称加密
*
* @param key 密钥
* @param plainText 明文
*/
public static String encrypt(String plainText, String key) throws Exception {
return encrypt(plainText, key, DEFAULT_IV);
}
/**
* 对称加密
*
* @param secretKey 密钥
* @param iv 加密向量,只有CBC模式才支持
* @param plainText 明文
*/
public static String encrypt(String plainText, String secretKey, String iv) throws Exception {
if (StringUtils.isAnyEmpty(plainText, secretKey, iv)) {
log.error("存在空值!!");
return null;
}
SecretKey key = new SecretKeySpec(DECODER.decode(secretKey), "AES");
byte[] plainTextInBytes = plainText.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(DECODER.decode(iv)));
return ENCODER.encodeToString(cipher.doFinal(plainTextInBytes));
}
/**
* 对称解密
*
* @param cipherText 密文
*/
public static String decrypt(String cipherText) throws Exception {
return decrypt(cipherText, DEFAULT_KEY);
}
/**
* 对称解密
*
* @param key 密钥
* @param cipherText 密文
*/
public static String decrypt(String cipherText, String key) throws Exception {
return decrypt(cipherText, key, DEFAULT_IV);
}
/**
* 对称解密
*
* @param secretKey 密钥
* @param iv 加密向量(需要16位byte数组字符串),只有CBC模式才支持
* @param ciphertext 密文
*/
public static String decrypt(String ciphertext, String secretKey, String iv) throws Exception {
if (StringUtils.isAnyEmpty(ciphertext, secretKey, iv)) {
log.error("存在空值!!");
return null;
}
SecretKey key = new SecretKeySpec(DECODER.decode(secretKey), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(DECODER.decode(iv));
byte[] ciphertextInBytes = DECODER.decode(ciphertext);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
return new String(cipher.doFinal(ciphertextInBytes), StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
String str = "hello word!";
String pwd = encrypt(str);
System.out.println("密文字符串1:" + pwd);
System.out.println(decrypt(pwd));
System.out.println("----------------------------");
byte[] bytes = new SecureRandom().generateSeed(16);
String key = ENCODER.encodeToString(bytes);
System.out.println("key2:");
pwd = encrypt(str, key);
System.out.println("密文字符串2:" + pwd);
System.out.println(decrypt(pwd, key));
System.out.println("----------------------------");
byte[] keyArr = new SecureRandom().generateSeed(16);
byte[] ivArr = new SecureRandom().generateSeed(16);
key = ENCODER.encodeToString(keyArr);
String iv = ENCODER.encodeToString(ivArr);
pwd = encrypt(str, key, iv);
System.out.println("key3:" + key);
System.out.println("iv3:" + iv);
System.out.println("密文字符串3:" + pwd);
System.out.println(decrypt(pwd, key, iv));
}
}
1.2 java测试结果
二、JavaScript前端
js端使用crypto-js实现 github仓库地址 https://github.com/brix/crypto-js/releases/tag/4.1.1
2.1 JavaScript代码
这里我直接下载源码然后新建个html页面测试
<body>
<script type="text/javascript" src="../crypto-js-4.1.1/crypto-js.js"></script>
<script type="text/javascript" src="../crypto-js-4.1.1/aes.js"></script>
<script type="text/javascript" src="../crypto-js-4.1.1/crypto-js.js"></script>
<script type="text/javascript">
function encryptByAES(plainText, keyInBase64Str, ivInBase64Str) {
let key = CryptoJS.enc.Base64.parse(keyInBase64Str)
let iv = CryptoJS.enc.Base64.parse(ivInBase64Str)
let encrypted = CryptoJS.AES.encrypt(plainText, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.ciphertext.toString(CryptoJS.enc.Base64)
}
function decryptByAES(cipherText, keyInBase64Str, ivInBase64Str) {
let key = CryptoJS.enc.Base64.parse(keyInBase64Str)
let iv = CryptoJS.enc.Base64.parse(ivInBase64Str)
// 返回的是一个Word Array Object,其实就是Java里的字节数组
let decrypted = CryptoJS.AES.decrypt(cipherText, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
</script>
</body>
2.2 测试结果
我是在浏览器的控制台进行的测试
2.2.1 js对java的密文字符串进行解密
2.2.2 js加密java解密