AOP实现接口加解密

接口加解密(主要实现分为 请求参数解密,返回参数加密 两个操作)
玩一下, 开搞,开搞!!!

目录

  • 实现思路
  • 引入maven
  • 核心代码
    • 自定义注解
    • AOP切面
    • 测试方法
    • 测试结果

实现思路

首先加解密用的就是各种加密算法进行处理的,之前我也发过多种加密方式的工具类(Java加密算法工具类(AES、DES、MD5、RSA)),其次就是用aop拦截处理,可以用自定义注解的形式定义是加密还是解密以及何种加解密方式,然后判断逻辑后在执行目标前后进行处理。aop拦截还有多种拦截方式我之前也有写过(JAVA三种拦截方式),可以参考下。

引入maven

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.6</version><scope>provided</scope>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

核心代码

自定义注解

其实这两个注解是可以合成一个使用的,这边为了对比明显

/*** 加密类型枚举* (对应工具类中各个加解密类型)*/
public enum EncryptType {AES,DES,MD5,RSA,NULL
}
import com.zhangximing.springboot_annotate.util.EncryptType;
import java.lang.annotation.*;/*** @Author: zhangximing* @Email: 530659058@qq.com* @Date: 2024/4/6 10:28* @Description: 自定义加密*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CustomEncryption {//加密类型EncryptType type() default EncryptType.NULL;}
import com.zhangximing.springboot_annotate.util.EncryptType;
import java.lang.annotation.*;/*** @Author: zhangximing* @Email: 530659058@qq.com* @Date: 2024/4/6 10:29* @Description: 自定义解密*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CustomDecryption {//解密类型EncryptType type() default EncryptType.NULL;}

AOP切面

注意算法部分参考之前(Java加密算法工具类(AES、DES、MD5、RSA))

import com.alibaba.fastjson.JSONObject;
import com.zhangximing.springboot_annotate.util.AESUtil;
import com.zhangximing.springboot_annotate.util.MD5Util;
import com.zhangximing.springboot_annotate.util.RSAUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** @Author: zhangximing* @Email: 530659058@qq.com* @Date: 2024/4/6 10:44* @Description: 加解密切面*/
@Aspect
@Configuration
public class SecurityInterceptor {// 拦截用过加密注释的@Pointcut("@annotation(com.zhangximing.springboot_annotate.annotate.CustomEncryption)")public void encPointCut(){}// 拦截用过解密注释的@Pointcut("@annotation(com.zhangximing.springboot_annotate.annotate.CustomDecryption)")public void decPointCut(){}@Around("decPointCut() || encPointCut()")public Object AroundCustomDecryption(ProceedingJoinPoint point){// 前置逻辑Object result = null;//获得当前访问的classClass<?> className = point.getTarget().getClass();//获得访问的方法名String methodName = point.getSignature().getName();//得到方法的参数的类型Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();//入参Object[] args = point.getArgs();JSONObject param = null;if (args != null && args.length > 0){param = JSONObject.parseObject(args[0].toString());}Method method = null;//解密try {// 得到访问的方法对象method = className.getMethod(methodName, argClass);// 判断是否存在@CustomDecryptionif (method.isAnnotationPresent(CustomDecryption.class) && param != null){CustomDecryption customDecryption = method.getAnnotation(CustomDecryption.class);System.out.println("使用算法:" + customDecryption.type());// 解密数据String encryptData = param.getString("encryptData");if (null == encryptData || "".equals(encryptData)){throw new RuntimeException("param error,encryptData is null");}String decryptData = "";System.out.println("解密前的数据:"+ encryptData);switch (customDecryption.type()){case AES:byte[] decrypted = AESUtil.decryptECB(AESUtil.key128, Base64.getDecoder().decode(encryptData));decryptData = new String(decrypted, StandardCharsets.UTF_8);break;case DES://jdk8才有sun.misc,这里不做展示break;case MD5://md5不支持解密throw new RuntimeException("md5 decrypt error");
//                        break;case RSA:byte[] bytes = RSAUtil.decryptPrivateKey(Base64.getDecoder().decode(encryptData), RSAUtil.getRsaPrivateKey);decryptData = new String(bytes);break;default:break;}System.out.println("解密后的数据:"+ decryptData);param.put("decryptData", decryptData);//替换请求入参args[0] = param;}} catch (Exception e) {e.printStackTrace();return e.getMessage();}// 执行目标方法try {result = point.proceed(args);} catch (Throwable e) {e.printStackTrace();return e.getMessage();}//加密try {// 判断是否存在@CustomEncryptionif (method.isAnnotationPresent(CustomEncryption.class) && result != null){CustomEncryption customEncryption = method.getAnnotation(CustomEncryption.class);System.out.println("使用算法:" + customEncryption.type());String encryptData = "";System.out.println("加密前的数据:"+ result);String beforeResult = JSONObject.toJSONString(result);if (beforeResult.length() > 2){beforeResult = beforeResult.substring(1, beforeResult.length() - 1);beforeResult = beforeResult.replaceAll("\\\\", "");}System.out.println("加密前处理的数据:"+ beforeResult);switch (customEncryption.type()){case AES:byte[] decrypted = AESUtil.encryptECB(AESUtil.key128, beforeResult.getBytes(StandardCharsets.UTF_8));encryptData = Base64.getEncoder().encodeToString(decrypted);break;case DES://jdk8才有sun.misc,这里不做展示break;case MD5:encryptData = MD5Util.getMd5(beforeResult);break;case RSA:byte[] bytes = RSAUtil.encryptPublicKey(beforeResult.getBytes(), RSAUtil.getRsaPublicKey);encryptData = Base64.getEncoder().encodeToString(bytes);break;default:break;}JSONObject resultJson = new JSONObject();System.out.println("加密后的数据:"+ encryptData);resultJson.put("encryptData",encryptData);result = resultJson.toJSONString();}}catch (Exception e){e.printStackTrace();return e.getMessage();}return result;}
}

测试方法

import com.alibaba.fastjson.JSONObject;
import com.zhangximing.springboot_annotate.annotate.CustomDecryption;
import com.zhangximing.springboot_annotate.annotate.CustomEncryption;
import com.zhangximing.springboot_annotate.util.EncryptType;
import org.springframework.web.bind.annotation.*;/*** 测试接口加解密*/
@RestController
@RequestMapping("/security")
public class SecurityController {//解密测试@CustomDecryption(type = EncryptType.RSA)@RequestMapping("/decrypt")public String decrypt(@RequestBody JSONObject param) {return param.toJSONString();}//加密测试@CustomEncryption(type = EncryptType.RSA)@RequestMapping("/encrypt")public String encrypt(@RequestBody JSONObject param) {param.put("success","ok");return param.toJSONString();}
}

测试结果

接口加密(可以看到返回了加密后的字符串)

在这里插入图片描述

接口解密(可以看到返回了加解密后的字符串)

在这里插入图片描述

控制台打印(统一设置了RSA算法)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/797103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3(domdiff)最长递归子序列求解简易版(超简单)

Vue3&#xff08;domdiff&#xff09;最长递归子序列求解简易版 ⚠️ 关键词&#xff08;每一个都需要理解&#xff09;js 代码实现写完感想欢迎关注 ⚠️ 关键词&#xff08;每一个都需要理解&#xff09; 动态规划&#xff08;O(N^2)&#xff09;&#xff08;不提倡&#xf…

python接入AI 实现微信自动回复

import numpy as np # 引入numpy库&#xff0c;目的是将读取的数据转换为列表 import pandas as pd # 引入pandas库&#xff0c;用来读取csv数据 from uiautomation import WindowControl # 引入uiautomation库中的WindowControl类&#xff0c;用来进行图像识别和模拟操作 i…

windows组播发不出去解决办法

由于开启了虚拟网卡&#xff0c;安装VMWare虚拟化软件&#xff0c;可能会通过虚拟网卡发送组播&#xff0c;需要禁用虚拟化网卡。

二分法题集1

1 二分查找 分析&#xff1a; 这是一道很简单的二分法题&#xff0c;定义两个指针和中间值middle&#xff0c;判断middle对应数组值与目标值的大小关系&#xff0c;从而对left和right进行修改。由于太过基础&#xff0c;代码简单基础就不多赘述。 目录 1 二分查找 分析&…

Android Framework 常见解决方案(28)system分区自定义方案

1 原理说明 一般在定制系统时&#xff0c;都会做预置apk和各类其他资源&#xff0c;很有可能超出系统默认设置的系统分区大小&#xff0c;也就会导致编译system时因超出默认设置的分区大小而失败。一般的做法是修改android framework时&#xff0c;修改对应项目的BOARD_SYSTEM…

干货 | 探索CUTTag:从样本到文库,实验步步为营!

CUT&Tag&#xff08;Cleavage Under Targets and Tagmentation&#xff09;是一种新型DNA-蛋白互作研究技术&#xff0c;主要用于研究转录因子或组蛋白修饰在全基因组上的结合或分布位点。相比于传统的ChIP-seq技术&#xff0c;CUT&Tag反应在细胞内进行&#xff0c;创新…

ccf 201703-1分蛋糕

// 分蛋糕 import java.util.Scanner;public class 分蛋糕 {public static void main(String[] args) {Scanner input new Scanner(System.in);int n input.nextInt(); // 蛋糕块数int k input.nextInt(); // 分发蛋糕的重量标准int[] arr new int[n];// 录入每块蛋糕的重量…

51单片机入门:LED点阵屏

LED点阵屏介绍 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种场合&#xff0c;如&#xff1a;广告屏、公告牌等。 分类&#xff1a; 按颜色&#xff1a;单色、双色、全彩&#x…

nuxt3配置打包静态资源在某一路径下

export default defineNuxtConfig({app: {baseURL: "/account-project"} });

ruoyi-nbcio-plus基于vue3的flowable流程设计器组件的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

银行ITSS体系下低代码运维体系实践分享

前言 自2021年中国人民银行发布《金融科技发展规划&#xff08;2022-2025年&#xff09;》以来&#xff0c;商业银行迈入数字化转型的高阶阶段。在此背景下&#xff0c;为了进一步提高金融科技的管理水平&#xff0c;商业银行需要改变传统金融运维模式&#xff0c;对已有运维体…

JUC:实现一个简易的数据库连接池(享元模式)

主要是学习享元模式。 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在通过共享尽可能多的对象来最小化内存使用和提高性能。在该模式中&#xff0c;对象被分为两种状态&#xff1a;内部状态和外部状态。 内部状态&#xff08;Intr…

红黑树插入机制深度剖析与实践指南

红黑树插入机制深度剖析与实践指南 一、红黑树的基本概念二、插入操作的初步2.1 RB-INSERT-FIXUP过程2.2 循环的不变性2.2.1 情况1&#xff1a;叔节点是红色2.2.2情况2和情况3&#xff1a;叔节点是黑色 三、插入操作的复杂性分析四、伪代码4.1 RB-INSERT 过程4.2 RB-INSERT-FIX…

亚信安慧AntDB:以数据之名,书写创新篇章

随着大数据时代的到来&#xff0c;对数据库的需求愈发强烈。在这一背景下&#xff0c;国产数据库逐渐崭露头角&#xff0c;亚信安慧AntDB作为重要的代表产品之一正积极参与到激烈的市场竞争中。亚信安慧AntDB不仅追求技术的革新和突破&#xff0c;同时也致力于满足用户日益增长…

4月06日,每日信息差

第一、中国电建设计承建的西藏八宿县100兆瓦保障性并网风电项目2日举行开工仪式。项目海拔高达5300米&#xff0c;刷新了之前同样由中国电建设计承建的西藏措美哲古风电场5200米的世界海拔最高风电场纪录 第二、宫崎骏新片《你想活出怎样的人生》上映第4天&#xff0c;中国内地…

理解PostgreSQL中的postmaster.pid

在PG中&#xff0c;一个简要的体系结构图可以大致画成下边的样子&#xff1a; Server端基本上分成backend process和若干background process。这些process都是一个名为postmaster进程的子进程。而postmaster则是postgres进程的别名。 进程概况 [14:42:08-postgrescentos1:/pg…

2024.4.2-day07-CSS 盒子模型(显示模式、盒子模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.2 学习笔记CSS标签元素显示模式1 块元素2 行内元素3 行内块元素4…

myweb项目资料集

项目要求 前后端分离后端采用 flask 框架前端采用 vue3 框架 后端部分 Flask 3 框架&#xff1a; https://dormousehole.readthedocs.io/en/latest/quickstart.html Session&#xff1a; https://blog.csdn.net/zhangvalue/article/details/93892241 MySQL 操作&#xf…

嵌入式学习48-单片机1

51单片机—————8位单片机 裸机驱动 无系统 linux驱动 有系统 驱动-----反映硬件变化 MCU 微控器 MPU CPU GPU 图像处理 IDE 集成开发环境 peripheral 外设 SOC&#xff1a; system on chip P0&#xff1a;8bit——8个引脚 位运算 & …

美国CPC认证是什么?为什么必须办理CPC认证呢?

美国CPC认证&#xff0c;全称为Childrens Product Certificate&#xff0c;是儿童产品认证的意思。它主要针对的是在美国市场销售的儿童产品&#xff0c;如玩具、家具、童车、餐椅、床上用品等。CPC认证要求产品安全性高&#xff0c;符合美国加州65、16 CFR等法规要求&#xff…