SpringBoot 实现数据加密脱敏(注解 反射 AOP)

星辰之海姬 2024-06-24 ⋅ 98 阅读

在实际项目中,我们经常需要对敏感数据进行加密和脱敏处理,以保护用户的隐私和数据安全。SpringBoot 提供了很多方便的功能,使得实现数据加密脱敏变得更加简单和高效。本篇博客将介绍如何利用SpringBoot的注解、反射和AOP技术来实现数据加密脱敏的功能。

加密和脱敏技术简介

加密(Encryption)是指将原始数据通过某种算法转换为密文,以防止未授权的访问和数据泄露。常用的加密算法有对称加密算法(如AES、DES)和非对称加密算法(如RSA)。

脱敏(Data Masking)是指对敏感数据进行部分隐藏或替换,以保护隐私信息。常见的脱敏方式有部分隐藏(如用星号代替部分字符)、字符替换(如用其他字符替换)、随机生成(如生成唯一ID)等。

实现原理

我们可以通过注解和AOP结合的方式,实现对特定字段进行加密和脱敏的功能。具体的实现原理如下:

  1. 首先,在需要做加密和脱敏处理的实体类字段上,使用自定义的注解进行标注。例如,我们可以创建一个@SensitiveInfo注解,用于标记需要做加密脱敏的字段。

  2. 利用反射机制,在运行时获取被@SensitiveInfo注解标记的字段。

  3. 使用加密和脱敏算法对字段进行处理。

  4. 利用AOP技术,在方法执行前后,对字段进行加密和脱敏操作。

实现步骤

  1. 创建一个自定义注解@SensitiveInfo,用于标记需要加密脱敏的字段。

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SensitiveInfo {
    }
    
  2. 创建一个切面类SensitiveInfoAspect,用于在方法执行前后进行加密和脱敏处理。

    @Aspect
    @Component
    public class SensitiveInfoAspect {
        @Before("@annotation(SensitiveInfo)")
        public void before(JoinPoint joinPoint) {
            // 在方法执行前进行加密和脱敏处理
        }
    
        @AfterReturning(value = "@annotation(SensitiveInfo)", returning = "returnValue")
        public void afterReturning(JoinPoint joinPoint, Object returnValue) {
            // 在方法执行后进行加密和脱敏处理
        }
    }
    
  3. 在需要进行加密和脱敏处理的实体类字段上,使用@SensitiveInfo注解进行标注。

    public class User {
        @SensitiveInfo
        private String name;
    
        @SensitiveInfo
        private String idCard;
    
        // 省略getter和setter方法
    }
    
  4. 在SpringBoot的配置类中,通过@EnableAspectJAutoProxy注解启用AOP。

    @Configuration
    @EnableAspectJAutoProxy
    public class AppConfig {
        // 配置其他Bean和组件
    }
    

加密和脱敏示例

接下来,我们以对用户姓名字段进行脱敏处理为例,演示一下加密和脱敏的实现。

  1. 创建一个自定义加密和脱敏算法类SensitiveDataUtils,提供对用户姓名字段的脱敏方法。

    @Component
    public class SensitiveDataUtils {
        public static String desensitizeName(String name) {
            StringBuilder sb = new StringBuilder();
            sb.append(name.charAt(0));
            for (int i = 1; i < name.length(); i++) {
                sb.append('*');
            }
            return sb.toString();
        }
    }
    
  2. SensitiveInfoAspectbeforeafterReturning方法中,对实体类字段进行加密和脱敏处理。

    @Aspect
    @Component
    public class SensitiveInfoAspect {
        private final SensitiveDataUtils sensitiveDataUtils;
    
        public SensitiveInfoAspect(SensitiveDataUtils sensitiveDataUtils) {
            this.sensitiveDataUtils = sensitiveDataUtils;
        }
    
        @Before("@annotation(SensitiveInfo)")
        public void before(JoinPoint joinPoint) {
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                Class<?> clazz = arg.getClass();
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(SensitiveInfo.class)) {
                        field.setAccessible(true);
                        try {
                            String name = field.getName();
                            Object value = field.get(arg);
                            if (value != null && value instanceof String) {
                                String desensitizedValue = sensitiveDataUtils.desensitizeName((String) value);
                                field.set(arg, desensitizedValue);
                                System.out.println("字段" + name + "的值已加密脱敏");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        @AfterReturning(value = "@annotation(SensitiveInfo)", returning = "returnValue")
        public void afterReturning(JoinPoint joinPoint, Object returnValue) {
            // 在方法执行后进行加密和脱敏处理
        }
    }
    
  3. 运行测试代码,查看结果。

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SensitiveInfoTest {
        @Autowired
        private SensitiveDataUtils sensitiveDataUtils;
    
        @Test
        public void testDesensitizeName() {
            String name = "张三";
            String desensitizedName = sensitiveDataUtils.desensitizeName(name);
            System.out.println("原始姓名:" + name);
            System.out.println("脱敏后的姓名:" + desensitizedName);
        }
    }
    

    运行结果:

    原始姓名:张三
    脱敏后的姓名:张*
    

总结

本篇博客介绍了如何利用SpringBoot的注解、反射和AOP技术实现数据加密和脱敏的功能。通过自定义注解、切面类和加密脱敏算法类的配合,可以在方法执行前后对指定字段进行加密和脱敏处理。这种方式简化了开发流程,提高了代码的可维护性和可扩展性。希望本篇博客能够帮助到您实现数据加密脱敏功能,在提升用户隐私和数据安全方面发挥积极作用。


全部评论: 0

    我有话说: