aes加密 js +java 实现
文章目录
1 js部分
1.1 加密工具类
var CryptoJS =require('crypto-js')
// 十六位十六进制数作为密钥
const SECRET_KEY = CryptoJS.enc.Utf8.parse("1234123412341234");
// 十六位十六进制数作为密钥偏移量
const SECRET_IV = CryptoJS.enc.Utf8.parse("1234123412341234");
/**
* 加密方法
* @param data
* @returns {string}
*/
function encrypt(data) {
if (typeof data === "object") {
try {
// eslint-disable-next-line no-param-reassign
data = JSON.stringify(data);
} catch (error) {
console.log("encrypt error:", error);
}
}
const dataHex = CryptoJS.enc.Utf8.parse(data);
const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}
/**
* 解密方法
* @param data
* @returns {string}
*/
function decrypt(data) {
const encryptedHexStr = CryptoJS.enc.Hex.parse(data);
const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
module.exports={
encrypt,decrypt
}
const data1 = [{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14},{name:"zhangsan",age:14}]
const encryptText = encrypt(data1);
console.log("加密", encryptText);
const decryptText = decrypt(encryptText);
console.log("解密", decryptText);
1.2 axios 统一加解密
const fs = require('fs')
const axios = require('axios');
const { encrypt,decrypt} = require('./tools/aestools');
const service =axios.create({
baseURL: "http://127.0.0.1:9010", // api的base_url process.env.BASE_API,,注意局域网访问时,不能使用localhost
timeout: 20 * 1000 // 请求超时时间
})
service.interceptors.request.use(config=>{
const {headers,data,params,url} = config
if(headers.rsa){
headers['content-type']="application/json"
config.data=encrypt(data)
}
return config
})
service.interceptors.response.use(response=>{
const {headers,data} =response
// console.log("headers", headers)
// console.log("data", data)
if(headers.rsa){
if(decrypt(data)){
const jiemi = decrypt(data)
// console.log("机密",jiemi);
const aa = JSON.parse(jiemi)
console.log(aa)
return aa
}
return null
}else{
return data
}
})
module.exports ={
service
}
1.3 测试类
const crypto = require('./rsa');
const request = require('./api/rsa')
const data =[{name:"1",code:112320},{name:"2",code:110}]
// for (let index = 0; index < 0; index++) {
// arr.push({name:'张三',code:"1222323",password:"密码超级无敌"});
// }
console.log(data)
request.rsaRequest(data).then(res=>{
//console.log(res)
})
2 JAVA 部分
2.1 加解密工具类
package com.liu.mac.crypto.utils;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
public class AESUtils {
private static final String ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
private static final String ALGORITHM_TYPE = "AES";
// int[] AES_KEYSIZES = new int[]{16, 24, 32}; aeskey 长度为16 24 32 三种情况
private static final String KEY = "1234123412341234";
// IV 的默认长度为16个字节
private static final String IV = "1234123412341234";
private static final String UTF8 = StandardCharsets.UTF_8.name();
/**
*
* @param text
* @return 加密后返回16进制字符串对象
* @throws Exception
*/
public static String encrypt(String text) throws Exception {
// 获取实例
Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
// 创建 加密的规则
SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
// 初始化加解密对象,设置key,和加密规则/解密规则
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(UTF8));
// cilper.init(Cipher.DECRYPT_MODE,secretKey);
cilper.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);
// cilper.init(Cipher.DECRYPT_MODE,secretKey);
byte[] doFinal = cilper.doFinal(text.getBytes(UTF8));
return Hex.encodeHexString(doFinal);
}
/**
*
* @param encodetext hex加密字符串
* @return 返回明文字符串
* @throws Exception
*/
public static String dencrypt(String encodetext) throws Exception {
// 获取实例
Cipher cilper = Cipher.getInstance(ALGORITHM_CBC);
// 创建 加密的规则
SecretKey secretKey = new SecretKeySpec(KEY.getBytes(UTF8), ALGORITHM_TYPE);
// 初始化加解密对象,设置key,和加密规则/解密规则
// cilper.init(Cipher.ENCRYPT_MODE, secretKey);
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(UTF8));
// cilper.init(Cipher.DECRYPT_MODE,secretKey);
cilper.init(Cipher.DECRYPT_MODE,secretKey,ivParameterSpec);
byte[] doFinal = cilper.doFinal( Hex.decodeHex(encodetext));
System.out.println(new String(doFinal,UTF8));
return new String(doFinal,UTF8);
}
/**
* 通过key生成指定长度的可以
* @param key
* @return
*/
private SecretKey generatorKey(String key)throws Exception{
// 创建keygenerator对象,可以根据传入的key生成一个指定长度的key
KeyGenerator keyGenerator =KeyGenerator.getInstance(ALGORITHM_CBC);
// 初始化 secureRandom,并指定生成指定长度key的算法
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(key.getBytes(UTF8));
keyGenerator.init(128,secureRandom);
SecretKey secretKey =keyGenerator.generateKey();
// 这里是通过秘钥获取,加密串
byte[] encoded = secretKey.getEncoded();
System.out.println(Hex.encodeHexString(encoded));
return secretKey;
}
@Test
public void test() throws Exception{
// String text = "我是超人我怕谁,212123";
// String encrypt = encrypt(text);
// System.out.println("HEX加密"+encrypt);z
//
String data2 = "8789a45fbad5da8f2bf28f9a315a3e1884e1fb1c410d7b815405d3e8736287cec07f0c788eeda5c7f761c6fe52bdd8fce99800b2522b02d561aa26bb2d5dcfef";
String encrypt="8789a45fbad5da8f2bf28f9a315a3e1884e1fb1c410d7b815405d3e8736287cec07f0c788eeda5c7f761c6fe52bdd8fce99800b2522b02d561aa26bb2d5dcfef";
System.out.println("解密"+dencrypt(encrypt));
// generatorKey("123");
}
}
2.2 参数解密
package com.liu.mac.crypto.advice;
import com.liu.mac.crypto.aop.ExcludeHttpBodyDecrypt;
import com.liu.mac.crypto.aop.HttpBodyDecrypt;
import com.liu.mac.crypto.utils.AESUtils;
import com.liu.mac.crypto.utils.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
@ControllerAdvice
@Slf4j
public class RequestBodyHandler implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
//排除解密注解
boolean methodHasExcludeHttpBodyDecrypt = methodParameter.hasMethodAnnotation(ExcludeHttpBodyDecrypt.class);
if (methodHasExcludeHttpBodyDecrypt) {
return false;
}
//解密注解
boolean methodHasHttpBodyDecrypt = methodParameter.hasMethodAnnotation(HttpBodyDecrypt.class);
if (methodHasHttpBodyDecrypt) {
return true;
}
boolean classHasExcludeHttpBodyDecrypt = methodParameter.getDeclaringClass().getAnnotation(ExcludeHttpBodyDecrypt.class) != null;
if (classHasExcludeHttpBodyDecrypt) {
return false;
}
boolean classHasHttpBodyDecrypt = methodParameter.getDeclaringClass().getAnnotation(HttpBodyDecrypt.class) != null;
if (classHasHttpBodyDecrypt) {
return true;
}
return false;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
System.out.println("beforeBodyRead");
if (inputMessage.getBody().available()<=0) {
return inputMessage;
}
byte[] requestDataByte=new byte[inputMessage.getBody().available()];
inputMessage.getBody().read(requestDataByte);
byte[] requestDataByteNew=null;
try {
String decode = new String( requestDataByte,"UTF-8").replace("\"","");
// 解密
requestDataByteNew = AESUtils.dencrypt(decode).getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
// 使用解密后的数据,构造新的读取流
InputStream rawInputStream = new ByteArrayInputStream(requestDataByteNew);
return new HttpInputMessage() {
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
@Override
public InputStream getBody() throws IOException {
return rawInputStream;
}
};
// return inputMessage;
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println("afterBodyRead");
log.info("请求体为]"+body);
return body;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
}
2.3 响应体加密
package com.liu.mac.crypto.advice;
import cn.hutool.json.JSONUtil;
import com.liu.mac.crypto.aop.ExcludeHttpBodyDecrypt;
import com.liu.mac.crypto.aop.HttpBodyDecrypt;
import com.liu.mac.crypto.utils.AESUtils;
import com.liu.mac.crypto.utils.RsaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@RestControllerAdvice
public class ResponseBodyHandler implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
//排除解密注解
boolean methodHasExcludeHttpBodyDecrypt = returnType.hasMethodAnnotation(ExcludeHttpBodyDecrypt.class);
if (methodHasExcludeHttpBodyDecrypt) {
return false;
}
//解密注解
boolean methodHasHttpBodyDecrypt = returnType.hasMethodAnnotation(HttpBodyDecrypt.class);
if (methodHasHttpBodyDecrypt) {
return true;
}
boolean classHasExcludeHttpBodyDecrypt = returnType.getDeclaringClass().getAnnotation(ExcludeHttpBodyDecrypt.class) != null;
if (classHasExcludeHttpBodyDecrypt) {
return false;
}
boolean classHasHttpBodyDecrypt = returnType.getDeclaringClass().getAnnotation(HttpBodyDecrypt.class) != null;
if (classHasHttpBodyDecrypt) {
return true;
}
return false;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
String content = JSONUtil.toJsonStr(body);
System.out.println(content);
response.getHeaders().set("rsa","true");
String result = null;
try {
result = AESUtils.encrypt(content);
System.out.println("返回后加密串为"+result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
2.4 加密注解/排除加密注解
package com.liu.mac.crypto.aop;
import java.lang.annotation.*;
/**
* 定义注解
* 功能:排除请求体/响应体解密/加密,请求体参数/响应不需要进行解密/加密
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcludeHttpBodyDecrypt {
}
package com.liu.mac.crypto.aop;
import java.lang.annotation.*;
/**
* 定义注解
* 功能:请求体/响应体解密/加密,请求体参数/响应需要进行解密/加密
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpBodyDecrypt {
}
2.5 测试接口类
package com.liu.mac.crypto.controller;
import cn.hutool.json.JSONUtil;
import com.liu.mac.crypto.aop.HttpBodyDecrypt;
import com.liu.mac.crypto.entity.User;
import com.liu.mac.crypto.utils.ResultVO;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/test")
public class CryptoController {
@HttpBodyDecrypt
@PostMapping("/info")
public ResultVO<User> restest(@RequestBody List<User> users){
System.out.println("users"+ JSONUtil.toJsonStr(users));
List<User> list = new ArrayList<>();
for (int i=1;i<25000;i++){
User user1 = new User();
user1.setCode(1110);
user1.setName("张三里斯");
user1.setPassword("23232323");
user1.setAge(i);
list.add(user1);
}
return ResultVO.ok("list",list);
}
}
3 前后端联调
F:\bigdata\cryptjs-test>node test
加密后:UH0/JPgvb5QM6RlYbeYIRU4Gzwb/pc6gGFeCF530StAY2WksoeFr6XPa7cz320TfT9ZLamOlC79THsMWOKhXj0atUiKdZssY7jFHTIE3wU5/c3/qeJdXXv7XWYcwYjZy1Hzx10bw4ADFkIEqowd1Lro2yDqU8xqcECVZ3M8Lm3w=
解密后:[{"name":"1"},{"name":"2"}]
加密 a6d59faae637c495f98b84172c18dbefb4c826a1795fa02b1f9aff91fdc421e4e095d5284ed9e154bcf0ee0b1858552b0d0085255232395af36062c025a061025874f99c70d5eccbd0532e29092e15f673a0561c774678ec339d7037b85d589db36e5916e6b3a6e9a67ba8d7393128d9f3d40d56e2c6078260e7740ade38878d8448f9f34a4b93295a8c99d7ba7c0d8a5a70b70f6f76efccb86c92dc07af4cde9decd322b0fc8d26591d1a4d04ced52aa7380e3252a3153f799abe6a6771439e4831e90f0e13d37ab5473a3abdea4e96f857714364c0e1c9981a566cd4eb6c5549fb962e2f095393bbc013c69c66d926
解密 [{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14},{"name":"zhangsan","age":14}][ { name: '1', code: 112320 }, { name: '2', code: 110 } ]
{
success: true,
code: 0,
message: 'list',
data: [
{ name: '张三里斯', code: 1110, age: 1, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 2, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 3, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 4, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 5, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 6, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 7, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 8, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 9, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 10, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 11, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 12, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 13, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 14, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 15, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 16, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 17, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 18, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 19, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 20, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 21, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 22, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 23, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 24, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 25, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 26, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 27, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 28, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 29, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 30, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 31, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 32, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 33, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 34, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 35, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 36, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 37, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 38, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 39, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 40, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 41, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 42, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 43, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 44, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 45, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 46, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 47, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 48, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 49, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 50, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 51, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 52, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 53, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 54, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 55, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 56, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 57, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 58, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 59, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 60, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 61, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 62, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 63, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 64, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 65, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 66, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 67, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 68, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 69, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 70, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 71, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 72, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 73, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 74, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 75, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 76, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 77, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 78, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 79, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 80, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 81, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 82, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 83, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 84, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 85, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 86, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 87, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 88, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 89, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 90, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 91, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 92, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 93, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 94, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 95, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 96, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 97, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 98, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 99, password: '23232323' },
{ name: '张三里斯', code: 1110, age: 100, password: '23232323' },
... 24899 more items
]
}
F:\bigdata\cryptjs-test>