java后端代码实现:使用javax.crypto包的功能,用16位的key和16位的偏移量,采用模式和补码方式为CBC/PKCS5Padding。
这里代码可参看参看:
Java 实现 AES 加密和解密完整示例_java aes加密-CSDN博客
但返回值时将加密结果使用Base64再次编码,由于Base64编码可能出现+和/,可能会引起URL内部的混乱,故模仿js中的encodeURIComponent方法,将+和/转化,方法如下:
/**
* 对url字符串进行编码
* @param url 待编码的url字符串
* @return 编码后的字符串
*/
public static String javaEncodeURIComponent(String url) {
try {
return URLEncoder.encode(url, "UTF-8").replace("+", "%20").replace("*", "%2A")
.replace("%7E", "~").replace("/", "%2F");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
}
}
返回值的书写形式就会变成:
// 将密文转换为 Base64 编码字符串,再转换可用的,可被js识别的url字符串
return javaEncodeURIComponent(Base64.getEncoder().encodeToString(string));
此时URL中参数部分的内容就会变成类似乱码的形式:
http://*****************/?NOKPRN
0aKYVAOGhkds03XvU%2BjKEFqk0GQsLRa1lz0cyvYhn35EYSVInVo00oRiJxh%2BT%2B0vuF%2FJOEY7909KZ2WqJTb.b4ZQm3kDiiN66zDY%3D
发送给前端后,利用crypto-js进行解密,注意解密时使用的编码模式,key和偏移量都需要和后端保持一致,否则容易出现解码结果为空的情况!但补码方式crypto-js默认使用PKCS#7。而在后端我们使用了PKCS#5。PKCS#7兼容PKCS#5,两者的区别可以参看此链接:
JAVA实现AES加密、解密 - 字节悦动 - 博客园 (cnblogs.com)
crypto-js安装:npm install crypto-js
先用decodeURIComponent函数处理URL中的参数部分,得到的字符串调用解密方法解密,加密解密可以放在新建的encryption.js文件中:
import CryptoJS from "crypto-js"; //引用AES源码js
var key = CryptoJS.enc.Utf8.parse("1234657812345678"); //十六位十六进制数作为秘钥
var iv = CryptoJS.enc.Utf8.parse("1234657812345678");//十六位十六进制数作为秘钥偏移量
//解密方法
export function Decrypt(decryptStr) {
const decryptBase64Str = CryptoJS.enc.Base64.parse(decryptStr);
const createCode = CryptoJS.lib.CipherParams.create({
ciphertext: decryptBase64Str,
});
const decryptedData = CryptoJS.AES.decrypt(createCode, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
const decryptedStr = CryptoJS.enc.Utf8.stringify(decryptedData).toString();
return decryptedStr;
}
//加密方法
export function Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
}
如果不希望用base64编码加密文件,还可以使用hex输出为16进制字符串:
将
byte[] encryptedBytes = cipher.doFinal(getBytes(text));
return javaEncodeURIComponent(Base64.getEncoder().encodeToString(encryptedBytes ));
改为:
return Hex.encodeHexString(cipher.doFinal(content.getBytes("UTF-8")));
但输出字符串较长,根据实际使用情况自省判断使用哪种方式。