Vue + springboot AES 对称解密前后端数据传输
后端导入maven
<!--加密算法-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
在pom.xml文件里添加以上配置
编写一个AES工具类
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
/**
* 加密工具类
*/
public class AesUtils {
public static String encrypt(String content, String key) {
try {
byte[] raw = key.getBytes(); //获得密码的字节数组
SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
Cipher cipher = Cipher.getInstance(ALGORITHMSTR); //根据指定算法ALGORITHM自成密码器
cipher.init(Cipher.ENCRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
byte [] byte_content = content.getBytes("utf-8"); //获取加密内容的字节数组(设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
byte [] encode_content = cipher.doFinal(byte_content); //密码器加密数据
return Base64.encodeBase64String(encode_content); //将加密后的数据转换为字符串返回
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decrypt(String encryptStr) {
try {
byte[] raw = loginKey.getBytes(); //获得密码的字节数组
SecretKeySpec skey = new SecretKeySpec(raw, "AES"); //根据密码生成AES密钥
Cipher cipher = Cipher.getInstance(ALGORITHMSTR); //根据指定算法ALGORITHM自成密码器
cipher.init(Cipher.DECRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
byte [] encode_content = Base64.decodeBase64(encryptStr); //把密文字符串转回密文字节数组
byte [] byte_content = cipher.doFinal(encode_content); //密码器解密数据
return new String(byte_content,"utf-8"); //将解密后的数据转换为字符串返回
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 生成16位秘钥
public static String getKey(){
String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz1234567890";
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 16; i++) {
builder.append(chars.indexOf(new Random().nextInt(chars.length())));
}
return builder.toString();
}
}
后端使用方法比较简单,调用方法即可
前端vue 安装加密算法的模块
使用 npm install crypto-js --save-dev
同时在需要使用加密的js文件里引入
import CryptoJS from 'crypto-js'
我这里创建一个AES.js 文件用于封装
注意 : AES 秘钥为16位,非16位会加密失败,前后端同理,可以使用代码生成,也可以自己设置
import CryptoJS from 'crypto-js' // npm install crypto-js --save-dev
export default {
//加密
encrypt(word, keyStr){
// 当未输入秘钥时,以下代码设置默认的秘钥
keyStr = keyStr ? keyStr : 'abcdefgabcdefg12';
var key = CryptoJS.enc.Utf8.parse(keyStr);//Latin1 w8m31+Yy/Nw6thPsMpO5fg==
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode:CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
},
//解密
decrypt(word, keyStr){
// 当未输入秘钥时,以下代码设置默认的秘钥
keyStr = keyStr ? keyStr : 'abcdefgabcdefg12';
let base64 = CryptoJS.enc.Base64.parse(word);
let src = CryptoJS.enc.Base64.stringify(base64);
var key = CryptoJS.enc.Utf8.parse(keyStr);//Latin1 w8m31+Yy/Nw6thPsMpO5fg==
var decrypt = CryptoJS.AES.decrypt(word, key, {
mode:CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
return decrypt.toString(CryptoJS.enc.Utf8).toString();
},
生成AES 16位秘钥
getKey(){
let len = 16;
let chars ='ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz1234567890';
let maxPos = chars.length;
let character = '';
for (let i = 0; i < len; i++) {
character += chars.charAt(Math.floor(Math.random() * maxPos))
}
return character;
}
}
前端使用
在需要使用加密的vue文件里导入
import AES from './util/AES.js'
var ss = AES.encrypt(str,key)
console.log("AES加密:"+ss)
console.log("AES解密 : " + AES.decrypt(ss,key))
在传输过程中推荐使用post请求,就参数封装在请求体里,
当前端向后端获取私密数据时有以下两种方案
一、
前端生成秘钥,将秘钥发送给后端,后端将加密数据返回前端
二、
前端发送获取数据请求,后端生成秘钥,将秘钥和数据加密后一并返回给前端
当前端向后端传输私密数据时
前端生成秘钥,将数据加密,将秘钥和加密数据一并传给后端,后端再根据业务逻辑进行数据和秘钥的存储或加解密