自定义注解,实现字段加密解密

news2024/11/25 8:34:56

根据业务需求,要求多部分字段,进行加解密,想到实现方式,就是通过自定义的注解+AOP来实现
首先新建一个注解,注意ElementType.FIELD类型,说明这个注解只能作用在字段上

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedEncrypt {
}

在新建一个切面类

@Aspect
@Component
public class EncryptionAspect {

    @Resource
    private EncryptionImpl encryptionService;

    //定义切点
    @Pointcut("within(com.bosssoft..*.*impl.*) && execution(* *(..))")
    public void pointCut(){}

    @Around("pointCut()")
    public Object encryptDecrypt(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        Object entity = args[0];

        // 加密前
        encryptFieldsBeforeSave(entity);

        // 执行方法
        Object result = joinPoint.proceed(args);

        // 解密后
        if (result != null) {
            decryptFieldsAfterQuery((Object) result);
        }

        return result;
    }

    private void encryptFieldsBeforeSave(Object entity) throws IllegalAccessException {
        Class<?> clazz = entity.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(NeedEncrypt.class)) {
                field.setAccessible(true);
                String value = (String) field.get(entity);
                if (value != null) {
                    String encryptedValue = encryptionService.encrypt(value);
                    field.set(entity, encryptedValue);
                }
            }
        }
    }

    private void decryptFieldsAfterQuery(Object entity) throws IllegalAccessException {
        Class<?> clazz = entity.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(NeedEncrypt.class)) {
                field.setAccessible(true);
                String value = (String) field.get(entity);
                if (value != null) {
                    String decryptedValue = encryptionService.decrypt(value);
                    field.set(entity, decryptedValue);
                }
            }
        }
    }
}

这个类中定义了切面,包含所有的实现类,以及实现类中所有的方法

下一步创建这个切面类的实现类,用来实现一些方法,比如:具体的加解密算法
本加密算法采用的是AES

@Component
public class EncryptionImpl {
    private static final String SECRET_KEY = "your_secret_key";
    private static final String ALGORITHM = "AES";

    public String encrypt(String valueToEncrypt) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedValue = cipher.doFinal(valueToEncrypt.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedValue);
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed", e);
        }
    }

    public String decrypt(String encryptedValue) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decodedValue = Base64.getDecoder().decode(encryptedValue);
            byte[] decryptedValue = cipher.doFinal(decodedValue);
            return new String(decryptedValue, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed", e);
        }
    }
}

注意的AES算法的密钥长度, 必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)

示例:
新增数据:
在这里插入图片描述

在这里插入图片描述
查询数据:
在这里插入图片描述

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

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

相关文章

合宙Air700ECQ硬件设计手册——应用接口2

Air700ECQ是一款高度集成的LTE Cat1无线通信模组&#xff0c;基于移芯EC716E平台设计&#xff0c;有着极小的封装和极高的性价比。 它支持移动双模FDD-LTE/TDD-LTE 4G远距离无线传输技术&#xff0c;能够广泛应用于共享设备、定位器、DTU数传等多种场景。 此外&#xff0c;Air7…

基于方面的情感分析研究综述——论文阅读笔记

前言 学习NLP领域知识时&#xff0c;先从情感分析入手。 在网上看到一篇方面级的情感分析综述性文章&#xff0c;觉得挺好的就找到其原来的论文进行阅读。 原文&#xff1a;《A Survey on Aspect-Based Sentiment Analysis: Tasks, Methods, and Challenges》 原文地址&#xf…

Python中定义和使用类的私有属性和方法

类的私有属性和方法指的是只能在类的内部使用&#xff0c;而不能在类外使用的属性和方法。 1 单下划线方式 在定义类的属性和方法时&#xff0c;在名字前面加一个下划线&#xff0c;此时表示该属性或方法只能在类的内部使用&#xff0c;而不能在类的外部使用&#xff0c;代码…

2024生成式AI商业落地白皮书_火山引擎

更多详细内容请下载资源 2024生成式AI商业落地白皮书-火山引擎

字符串函数———C语言

1. 求字符串的长度 strlen 原型&#xff1a;size_t strlen(const char *str); 原理&#xff1a;字符串以\0作为结束标志&#xff0c;strlen函数返回的是在字符串中\0前面出现的字符个数&#xff08;不包括\0&#xff09;参数指向的字符串必须要以\0结束 #include <stdio…

配置策略路由实战 附带基础网络知识

背景 作为一个软件开发人员&#xff0c;不可能做到只负责业务开发工作&#xff0c;一旦功能上线或者系统切换就会遇到非常多考验开发人员个人能力的场景&#xff0c;网络调整就是非常重要的一个方面&#xff0c;如果你在系统上线的过程中无法处理一些简单的网络问题或者听不懂…

SpringBoot的内置缓存以及整合第三方缓存

一、什么是缓存 企业级应用主要作用是信息处理&#xff0c;当需要读取数据时&#xff0c;由于受限于数据库的访问效率&#xff0c;导致整体系统性能偏低。 应用程序直接与数据库打交道&#xff0c;访问效率低 为了改善上述现象&#xff0c;开发者通常会在应用程序与数据库之间建…

【避雷】Fomepay跑路大揭秘!还我q来!

震惊&#xff01;Fomepay公司一夜之间消失无踪&#xff0c;用户资金不翼而飞&#xff01; 首先&#xff0c;讲一下我自己的经历&#xff0c;想使用fomepay开卡订阅gpt&#xff0c;充值两百多后&#xff0c;想提现客服直接跑路&#xff01;充多少吞多少&#xff01;骗子公司&am…

Linux pstree 命令详解

pstree 命令是一个在 Unix-like 系统中用于以树状图的形式显示当前运行的进程的命令。这种展示方式比简单的列表&#xff08;ps查看&#xff09;更加直观&#xff0c;有助于用户快速理解进程的层次结构和父子关系。 在诊断系统问题时&#xff0c;pstree 可以帮助确定哪些进程是…

预警先行,弯道哨兵让行车更安全

预警先行&#xff0c;弯道哨兵让行车更安全”这句话深刻体现了现代交通安全理念中预防为主、科技赋能的重要性。在道路交通中&#xff0c;尤其是复杂多变的弯道区域&#xff0c;交通事故的发生率往往较高&#xff0c;因此&#xff0c;采取有效的预警措施和引入先进的交通辅助设…

windows bash获取一个目录下所有的文件

在Windows系统中&#xff0c;我们可以使用命令行工具来获取文件夹下的所有文件名。具体操作如下&#xff1a; 1. 打开命令提示符&#xff08;WinR&#xff0c;输入cmd&#xff0c;回车&#xff09;&#xff1b; 2. 进入需要提取文件名的文件夹&#xff08;使用cd命令&#xf…

从0开始搭建个人博客《第十一期:优化网站访问速度》

目录 一、背景说明 二、Nginx性能优化 &#xff08;一&#xff09;文件句柄 1.系统全局性修改和用户局部性修改 2.进程局部性修改 &#xff08;二&#xff09;CPU亲和配置 1.设置工作进程数 2.设置连接数 &#xff08;三&#xff09;事件处理模型优化 &#xff08;四&…

VisualStudio:模块概念、引用概念及方法、Debug与Release说明

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 今天学习VisualStudio软件的相关内容&#xff0c;以下为学习笔记。 01 模块的概念 模块通常是按照功能划分组成的各个类库或可启动项。 一个模块可以是一个类库&#xff0c;也可以是多个类库&#xff0c;还可以包括…

【机器学习】经典CNN架构

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 经典CNN架构1. 引言2. LeNet3. AlexNet4. VGGNet5. GoogLeNet(Inception)6. Res…

世上最简单的安装jenkins

注意&#xff1a;本次安装的jenkins只支持jdk1.8版本 下载地址&#xff08;jenkins版本2.346&#xff09;&#xff1a; https://mirrors.jenkins-ci.org/war/2.346/ 1、在本地电脑jenkins.war包存放地址里面新建run.bat文件 内容&#xff1a;java -jar D:\install\jenkins\…

宝塔安装python新版本并使用

情况说明&#xff1a; 不是切换宝塔面板默认的 python 而是单独安装一个python版本&#xff0c;然后通过 终端 或者PHP的 shell_exec 方法可以调用。我当前宝塔面板默认的python版本是3.6.8&#xff0c;由于需要用到的python库只支持3.8以上&#xff0c;所以要安装新的python版…

【Java】——Java程序实现学生成绩输入与等级划分

在本文中&#xff0c;我们将介绍如何使用Java编写一个简单的程序&#xff0c;用于输入学生的成绩并划分等级。这个程序可以实现以下功能&#xff1a; 输入学生人数。输入每个学生的成绩。计算最高分。根据最高分划分成绩等级。输出每个学生的分数和对应的等级。 首先&#xff…

SAP B1 三大基本表单标准功能介绍-业务伙伴主数据(四)

背景 在 SAP B1 中&#xff0c;科目表、业务伙伴主数据、物料主数据被称为三大基本表单&#xff0c;其中的标准功能是实施项目的基础。本系列文章将逐一介绍三大基本表单各个字段的含义、须填内容、功能等内容。 附上 SAP B1 10.0 的帮助文档&#xff1a;SAP Business One 10…

数学建模学习(115):主成分分析(PCA)与Python实践

文章目录 一.主成分分析简介1.1 数学背景与维度诅咒1.2 PCA的定义与应用二.协方差矩阵——特征值和特征向量三.如何为数据集选择主成分数量四.特征提取方法五.LDA——与PCA的区别六.PCA的应用七.PCA在异常检测中的应用八.总结一.主成分分析简介 1.1 数学背景与维度诅咒 主成成…

【Python爬虫】教你追剧看电影不求人!python爬虫代码教你爬取各平台视频,小白也能学会!附源码

看剧看一半不是VIP就是svip&#xff0c;正当我们看的津津有味的时候&#xff0c;让你冲米弹窗出来了&#xff01;&#xff01;&#xff01; 对于大家来说&#xff0c;想看续集&#xff0c;都是全凭实力刷续集。 如果这时候你会Python的话&#xff0c;那就不会有这些烦恼了&…