springboot项目前后端实现AES加解密
后端代码如下:
1、EncryptionUtils? 这是加解密工具类
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
/**
* @ClassName EncryptionUtils
* @Description: TODO
* @Author LRH
* @Date 2023/12/14
* @Version V1.0
**/
public class EncryptionUtils {
/**
* Description: 配合前端CryptoJS实现加密、解密工作。
* CryptoJS 是一个 JavaScript 库,提供了一系列密码学函数和工具,用于加密、解密、生成摘要等任务。
* 它支持多种加密算法,包括常见的对称加密算法(如 AES、DES)和非对称加密算法(如 RSA)。
*/
private final static String IV = "67890123456";//需要前端与后端配置一致
private final static String KEY = "1234567890123456";
/**
* 加密算法,使用默认的IV、KEY
* @param content
* @return
*/
public static String encrypt(String content){
return encrypt(content,KEY,IV);
}
/**
* 解密算法,使用默认的IV、KEY
* @param content
* @return
*/
public static String decrypt(String content){
return decrypt(content,KEY,IV);
}
/**
* 加密方法
* @param content
* @param key
* @param iv
* @return
*/
public static String encrypt(String content, String key, String iv){
try{
// "算法/模式/补码方式"NoPadding PkcsPadding
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
int blockSize = cipher.getBlockSize();
byte[] dataBytes = content.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
return Base64.getEncoder().encodeToString(encrypted);
}catch (Exception e) {
throw new RuntimeException("加密算法异常 CryptoUtil encrypt()加密方法,异常信息:" + e.getMessage());
}
}
/**
* 解密方法
* @param content
* @param key
* @param iv
* @return
*/
public static String decrypt(String content, String key, String iv){
try {
byte[] encrypted1 = Base64.getDecoder().decode(content);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] original = cipher.doFinal(encrypted1);
return new String(original).trim();
} catch (Exception e) {
throw new RuntimeException("加密算法异常 CryptoUtil decrypt()解密方法,异常信息:" + e.getMessage());
}
}
public static void main(String[] args) {
String str = "98B197CA526C5B2749F305DDB34233F7B8F4F9C09F83FEA6B6A2D98FFAE05A64";
System.out.println(decrypt(str));
}
}
2、解码处理类DecodeInputMessage
/**
* 解码处理
* @author rstyro
*/
@Slf4j
public class DecodeInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public DecodeInputMessage(HttpInputMessage httpInputMessage) {
try {
// 2、从inputStreamReader 得到aes 加密的内容
String encodeAesContent = new BufferedReader(new InputStreamReader(httpInputMessage.getBody())).lines().collect(Collectors.joining(System.lineSeparator()));
JSONObject jsonObject = JSON.parseObject(encodeAesContent);
// 3、AES通过密钥CBC解码
String str = jsonObject.getString("data");
String aesDecode = EncryptionUtils.decrypt(str);
if (!StringUtils.isEmpty(aesDecode)) {
// 4、重新写入到controller
this.body = new ByteArrayInputStream(aesDecode.getBytes());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public InputStream getBody() throws IOException {
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}
3、控制器监听EncryptRequestAdvice类
import org.springframework.core.MethodParameter;
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.IOException;
import java.lang.reflect.Type;
/**
* 请求参数到controller之前的处理
* @author rstyro
*/
@ControllerAdvice(basePackages = {"shengyun.controller"})
public class EncryptRequestAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
return new DecodeInputMessage(httpInputMessage);
}
@Override
public Object afterBodyRead(Object obj, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
// 这里就是已经读取到body了,obj就是
return obj;
}
@Override
public Object handleEmptyBody(Object obj, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
// body 为空的时候调用
return obj;
}
}
4、结果返回工具类
?
public class ResultUtil {
private static Logger logger = LoggerFactory.getLogger(ResultUtil.class);
public static ResultVO<Object> success(Object object) {
ResultVO<Object> resultVO = new ResultVO<>();
if(object instanceof String){
resultVO.setData(object);
}else {
// 配置项
SerializerFeature feature = SerializerFeature.WriteDateUseDateFormat;
resultVO.setData(EncryptionUtils.encrypt(JSONObject.toJSONString(object,feature)));
}
resultVO.setCode(200);
resultVO.setMsg("success");
logger.info("返回参数:{}", JSONObject.toJSONString(resultVO));
return resultVO;
}
public static ResultVO<Object> success() {
return success(null);
}
public static ResultVO<Object> success(Object object, String msg) {
ResultVO<Object> resultVO = new ResultVO<>();
resultVO.setData(object);
resultVO.setCode(200);
resultVO.setMsg(msg);
return resultVO;
}
public static ResultVO<Object> error(Integer status, String msg) {
ResultVO<Object> resultVO = new ResultVO<>();
resultVO.setCode(status);
resultVO.setMsg(msg);
return resultVO;
}
}
5、接口返回实体类
@Data
public class ResultVO<T> implements Serializable {
private Integer code;
private String msg;
private T data;
}
前端引入import CryptoJS from '@/uni_modules/crypto-js'
// 密钥和偏移量
const key = 'your-key'
const iv = 'your-iv'
// 加密函数
const encrypt = (data) => {
? const keyBytes = CryptoJS.enc.Utf8.parse(key)
? const ivBytes = CryptoJS.enc.Utf8.parse(iv)
debugger
? const encrypted = CryptoJS.AES.encrypt(data, keyBytes, {
? ? iv: ivBytes,
? ? mode: CryptoJS.mode.CBC,
? ? padding: CryptoJS.pad.NoPadding,
? })
? return encrypted.toString()
}
// 解密函数
const decrypt = (encryptedData) => {
? const cipherText = CryptoJS.enc.Base64.parse(encryptedData);
? const keyBytes = CryptoJS.enc.Utf8.parse(key);
? const ivBytes = CryptoJS.enc.Utf8.parse(iv);
? const decipher = CryptoJS.AES.decrypt(
? ? {
? ? ? ciphertext: cipherText,
? ? },
? ? keyBytes,
? ? {
? ? ? iv: ivBytes,
? ? ? mode: CryptoJS.mode.CBC,
? ? ? padding: CryptoJS.pad.NoPadding,
? ? }
? );
? const decryptedData = CryptoJS.enc.Utf8.stringify(decipher);
? return decryptedData;
}
// GET请求
const get = (data = {}, options = {}) => {
?? ?options.showLoading = data.showLoading || true
?? ?options.url = data.url
?? ?options.method = 'GET'
?? ?options.data = encrypt(data.data)
?? ?return request(options)
}
// POST请求
const post = (data = {}, options = {}) => {
?? ?options.showLoading = data.showLoading || true
?? ?options.showMask = data.showMask || false
?? ?options.showErrorToast = data.showErrorToast!=1
?? ?options.isForm = data.isForm || false
?? ?options.url = data.url
?? ?options.method = 'POST'
?? ?options.data = encrypt(data.data)
?? ?return request(options)
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!