当前位置:   article > 正文

SpringBoot实战:轻松实现接口数据脱敏_接口数据脱敏原理

接口数据脱敏原理

一、接口数据脱敏概述

1.1 接口数据脱敏的定义

接口数据脱敏是Web应用程序中一种保护敏感信息不被泄露的关键措施。在API接口向客户端返回数据时,系统会对包含敏感信息(如个人身份信息、财务数据等)的字段进行特殊处理。这种处理通过应用特定的算法或遵循既定规则,将敏感字段的部分或全部内容隐藏或替换,例如使用星号(*)或其他占位符来掩盖关键信息,同时尽量保持数据的原有格式和可读性(在合理范围内),以确保敏感数据不会直接暴露给未经授权的访问者。

1.2 接口数据脱敏的重要性

数据脱敏的重要性不言而喻,它主要体现在以下几个核心方面:

  1. 强化用户隐私保护:对个人敏感信息,如姓名、身份证号码、手机号码等,进行脱敏处理,是保护用户隐私的有效手段。这种措施能够防止敏感信息被非法获取和滥用,维护用户的合法权益。

  2. 确保法律合规性:随着全球范围内数据保护法规的日益严格,如欧盟的《通用数据保护条例》(GDPR)和中国的《个人信息保护法》等,实施数据脱敏已成为企业合规运营的重要一环。通过脱敏处理,企业能够避免触犯相关法律条款,减少因违规而产生的法律风险。

  3. 降低数据泄露风险:即便在数据不慎泄露的情况下,经过脱敏处理的数据也能显著降低敏感信息被直接利用的风险。这有助于减轻因数据泄露给企业、用户及社会带来的潜在危害。

  4. 促进数据的安全共享与利用:在保护个人隐私的前提下,脱敏后的数据仍保留了足够的分析价值,为数据的安全共享和有效利用提供了可能。这有助于推动数据在合规框架内的流通与融合,促进数据价值的最大化释放。

1.3 接口数据脱敏的实现方式

手动脱敏:直接在业务逻辑层代码中对敏感数据进行逐一处理,这种方式虽然提供了较高的灵活性,但容易因人为疏忽而导致脱敏遗漏,同时也会导致代码中存在大量的重复处理逻辑,增加了维护成本。

AOP(面向切面编程):利用AOP技术,通过定义切面来拦截API接口返回的数据流,从而实现对敏感字段的统一处理。这种方法能够将脱敏逻辑从业务代码中抽离出来,实现集中管理,提高了代码的可维护性和可扩展性。然而,由于AOP的拦截机制会增加一定的处理开销,因此可能会对系统性能产生一定的影响。

自定义序列化器:在数据序列化阶段,通过集成JSON序列化框架(如Jackson)提供的自定义序列化器功能,实现对敏感字段的自动化处理。这种方法既保持了较好的性能表现,又能够将脱敏逻辑与业务逻辑完全解耦,使得代码更加清晰和易于管理。

注解+反射:通过定义自定义注解来标记那些需要进行脱敏处理的字段,然后在数据返回前,利用Java的反射机制在运行时动态地遍历这些字段并进行脱敏处理。这种方式简化了脱敏操作的使用过程,使得开发者只需通过简单的注解标记即可实现脱敏功能,同时也有利于后续对脱敏逻辑的维护和扩展。

二、开发环境

  • JDK版本:JDK 17

  • Spring Boot版本:Spring Boot 3.2.2

  • 构建工具:Maven

三、实现接口返回数据脱敏

3.1 添加依赖

首先在 pom.xml 文件中添加必要的依赖:

  1. <dependency>
  2.         <groupId>cn.hutool</groupId>
  3.         <artifactId>hutool-all</artifactId>
  4.         <version>5.8.25</version>
  5.     </dependency>
  6.     
  7.     <dependency>
  8.         <groupId>com.fasterxml.jackson.core</groupId>
  9.         <artifactId>jackson-databind</artifactId>
  10.         <version>2.9.2</version>
  11.     </dependency>

3.2 创建自定义注解

接下来,我们创建一个自定义注解 @Desensitize

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.FIELD)
  3. @JacksonAnnotationsInside
  4. @JsonSerialize(using = DesensitizeSerializer.class)
  5. public @interface Desensitize {
  6.     
  7.     DesensitizeType type() default DesensitizeType.DEFAULT;
  8.     
  9.     int startInclude() default 0;
  10.     
  11.     int endExclude() default 0;
  12.     
  13. }

3.3 定义脱敏枚举类

然后,定义枚举类 DesensitizeType 来定义字段的脱敏类型:

  1. public enum DesensitizeType {
  2.     
  3.     DEFAULT,
  4.     
  5.     CUSTOM_RULE,
  6.     
  7.     PHONE,
  8.     
  9.     EMAIL,
  10.     
  11.     ID_CARD,
  12.     
  13.     BANK_CARD,
  14.     
  15.     ADDRESS,
  16.     
  17.     CHINESE_NAME,
  18.     
  19.     PASSWORD,
  20. }

3.4 创建自定义序列化类

Hutool支持的脱敏数据类型包括:

  1. 用户id

  2. 中文姓名

  3. 身份证号

  4. 座机号

  5. 手机号

  6. 地址

  7. 电子邮件

  8. 密码

  9. 中国大陆车牌,包含普通车辆、新能源车辆

  10. 银行卡

整体来说,所谓脱敏就是隐藏掉信息中的一部分关键信息,用*代替。大家可以自己看一看DesensitizedUtil类中方法,其实就是replace方法和hide方法的使用,想要自定义规则进行隐藏可以仿照进行实现。

  1. public class DesensitizeSerializer extends JsonSerializer<Stringimplements ContextualSerializer {
  2.     
  3.     private DesensitizeType type;
  4.     
  5.     private int startInclude;
  6.     
  7.     private int endExclude;
  8.     public DesensitizeSerializer() {
  9.         this.type = DesensitizeType.DEFAULT;
  10.     }
  11.     public DesensitizeSerializer(DesensitizeType type) {
  12.         this.type = type;
  13.     }
  14.     
  15.     @Override
  16.     public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
  17.         switch (type) {
  18.             case CUSTOM_RULE:
  19.                 
  20.                 gen.writeString(StrUtil.hide(value, startInclude, endExclude));
  21.                 break;
  22.             case PHONE:
  23.                 gen.writeString(DesensitizedUtil.mobilePhone(value));
  24.                 break;
  25.             case EMAIL:
  26.                 gen.writeString(DesensitizedUtil.email(value));
  27.                 break;
  28.             case ID_CARD:
  29.                 gen.writeString(DesensitizedUtil.idCardNum(value, 12));
  30.                 break;
  31.             case BANK_CARD:
  32.                 gen.writeString(DesensitizedUtil.bankCard(value));
  33.                 break;
  34.             case ADDRESS:
  35.                 gen.writeString(DesensitizedUtil.address(value, 8));
  36.                 break;
  37.             case CHINESE_NAME:
  38.                 gen.writeString(DesensitizedUtil.chineseName(value));
  39.                 break;
  40.             case PASSWORD:
  41.                 gen.writeString(DesensitizedUtil.password(value));
  42.                 break;
  43.             default:
  44.                 gen.writeString(value);
  45.                 break;
  46.         }
  47.     }
  48.     
  49.     @Override
  50.     public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
  51.         if (property != null) {
  52.             Desensitize annotation = property.getAnnotation(Desensitize.class);
  53.             if (annotation != null) {
  54.                 this.type = annotation.type();
  55.                 if (annotation.type() == DesensitizeType.CUSTOM_RULE) {
  56.                     this.startInclude = annotation.startInclude();
  57.                     this.endExclude = annotation.endExclude();
  58.                 }
  59.             }
  60.         }
  61.         return this;
  62.     }
  63. }

代码分析:

  • serialize方法在序列化字符串时被调用,根据脱敏类型对字符串进行相应的脱敏处理。根据不同的脱敏类型,使用不同的处理方法对字符串进行脱敏,并将处理后的字符串写入JSON生成器中。

  • createContextual方法根据上下文信息创建自定义的序列化器,用于处理带有@Desensitize注解的属性。它通过获取注解中的脱敏类型和自定义规则的起始位置和结束位置,对实例进行相应的设置,并返回自定义的序列化器实例。

这个序列化器的主要用途是在 JSON 序列化过程中自动对标记了 @Desensitize 注解的字段进行脱敏处理。

四、测试

4.1 编写测试代码

  1. 编写实体类

    1. @Data
    2. public class UserDTO {
    3.     
    4.     @Desensitize(type = DesensitizeType.CHINESE_NAME)
    5.     private String name;
    6.     
    7.     @Desensitize(type = DesensitizeType.PHONE)
    8.     private String phoneNumber;
    9.     
    10.     @Desensitize(type = DesensitizeType.EMAIL)
    11.     private String email;
    12.     
    13.     @Desensitize(type = DesensitizeType.PASSWORD)
    14.     private String password;
    15.     
    16.     @Desensitize(type = DesensitizeType.ID_CARD)
    17.     private String idCard;
    18.     
    19.     @Desensitize(type = DesensitizeType.BANK_CARD)
    20.     private String bankCard;
    21.     
    22.     @Desensitize(type = DesensitizeType.ADDRESS)
    23.     private String address;
    24.     
    25.     @Desensitize(type = DesensitizeType.CUSTOM_RULE, startInclude = 2, endExclude = 6)
    26.     private String gameName;
    27. }

  2. 编写测试接口

  1. @RestController
  2. @RequestMapping("/test")
  3. public class TestController {
  4.     
  5.     @GetMapping("/desensitize")
  6.     public UserDTO getUser() {
  7.         UserDTO userDTO = new UserDTO();
  8.         userDTO.setName("孙大圣");
  9.         userDTO.setEmail("shijun@163.com");
  10.         userDTO.setPhoneNumber("12345678901");
  11.         userDTO.setPassword("123456");
  12.         userDTO.setAddress("辽宁省盘锦市兴隆台区红村乡441号");
  13.         userDTO.setIdCard("447465200912089605");
  14.         userDTO.setBankCard("6217000000000000000");
  15.         userDTO.setGameName("超级无敌大铁锤");
  16.         return userDTO;
  17.     }
  18. }

4.2 测试

五、总结

本文深入探讨了在SpringBoot应用程序中实施数据脱敏策略的关键性,并提出了一种创新的解决方案,即通过集成自定义注解与Hutool脱敏工具类来高效地实现数据脱敏。此方案旨在精准地对敏感信息进行脱敏处理,确保用户隐私得到妥善保护,同时维护数据的安全性。我们期待这一方案能为开发者们提供有价值的参考,共同提升数据保护水平。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/920882
推荐阅读
相关标签