注解实现数据脱敏

数据脱敏

什么是数据脱敏

数据脱敏(Data Masking)是一种数据安全技术,旨在通过预先设定的规则和算法,对原始数据中包含的敏感信息进行变形处理,使得这些信息在非生产环境(例如开发、测试、分析或培训场景)中使用时,既能保持原有数据格式和业务逻辑的真实性,又能有效保护个人隐私和商业机密不被泄露。

在实施数据脱敏时,对诸如身份证号、手机号、银行卡号、个人姓名、家庭住址、电子邮件地址、医疗记录等敏感信息采取替换、遮盖、乱序、加密、截断等手段进行处理,以防止这些敏感信息在未经授权的情况下被识别或滥用。

具体脱敏规则可以包括但不限于:

  • 替换:例如将身份证号的部分数字替换为“*”或随机数。

  • 随机化:例如生成与真实数据格式相符但与原始数据无关的新数据。

  • 固定模式脱敏:例如保留电话号码的区号和最后几位,其余部分替换。

  • 加密:对数据进行不可逆或可逆加密,仅在必要时解密。

  • 假名化:用虚构的名字替换真实姓名。

1.创建spring项目,导入依赖

 <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.18</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--        json模快-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-json</artifactId>
        </dependency>

 

2.自定义枚举类DesensitizationTypeEnum

public enum DesensitizationTypeEnum {
    //自定义
    CUSTOMER,
    //用户id
    USER_ID,
    //中文姓名
    CHINESE_NAME,
    //身份证号
    ID_CARD,
    //座机号
    FIXED_PHONE,
    //手机号
    MOBILE_PHONE,
    //地址
    ADDRESS,
    //电子邮件
    EMAIL,
    //密码
    PASSWORD,
    //中国大陆车牌,包含普通车辆、新能源车辆
    CAR_LICENSE,
    //银行卡
    BANK_CARD,
}

3.创建自定义的序列化脱敏类

@NoArgsConstructor
@AllArgsConstructor
public class DesensitizationSerialize extends JsonSerializer<String> implements ContextualSerializer {
    // 保存敏感信息处理规则的枚举
    private DesensitizationTypeEnum type;

    private Integer startInclude;

    private Integer endExclude;
    // JsonGenerator 主要用于生成 JSON 数据并将其输出到各种类型的输出流
    //serialize 方法本身并不直接提供数据脱敏功能,它主要是为了将表单数据转换为可传输的字符串格式
    @Override
    public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        switch (type) {
            //自定义 Java 对象如何序列化成 JSON 格式
            // 自定义类型脱敏
            case CUSTOMER:
                //通过使用 CharSequenceUtil 类,开发者可以更加方便地进行字符串相关的编程工作,避免了重复编写基础的字符串处理逻辑
                jsonGenerator.writeString(CharSequenceUtil.hide(str,startInclude,endExclude));
                break;
            // userId脱敏
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId()));
                break;
            // 中文姓名脱敏
            case CHINESE_NAME:
                jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str)));
                break;
            // 身份证脱敏
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2));
                break;
            // 固定电话脱敏
            case FIXED_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str)));
                break;
            // 手机号脱敏
            case MOBILE_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str)));
                break;
            // 地址脱敏
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str), 8));
                break;
            // 邮箱脱敏
            case EMAIL:
                jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str)));
                break;
            // 密码脱敏
            case PASSWORD:
                jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str)));
                break;
            // 中国车牌脱敏
            case CAR_LICENSE:
                jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str)));
                break;
            // 银行卡脱敏
            case BANK_CARD:
                jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str)));
                break;
            default:
        }
    }

    //BeanProperty 参数代表Java Bean中正在被反序列化的属性,  初始化或定制该反序列化器的行为。
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            // 判断数据类型是否为String类型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                // 获取定义的注解
                Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);
                // 为null
                if (desensitization == null) {
                    //就可以通过 getContextAnnotation 来找到这个注解并据此调整属性的序列化或反序列化行为
                    desensitization = beanProperty.getContextAnnotation(Desensitization.class);
                }
                // 不为null
                if (desensitization != null) {
                    // 创建定义的序列化类的实例并且返回,入参为注解定义的type,开始位置,结束位置。
                    return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(),
                            desensitization.endExclude());
                }
            }
            //查找和提供合适的序列化器(JsonSerializer)来处理给定类型的数据
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}

4.测试:创建实例类添加脱敏注解

@Data
public class TestAnnotationDTO implements Serializable {
    /**
     * 自定义
     */
    @Desensitization(type = DesensitizationTypeEnum.CUSTOMER,startInclude = 5,endExclude = 10)
    private String custom;
    /**
     * 手机号
     */
    @Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)
    private String phone;
    /**
     * 邮箱
     */
    @Desensitization(type = DesensitizationTypeEnum.EMAIL)
    private String email;
    /**
     * 身份证
     */
    @Desensitization(type = DesensitizationTypeEnum.ID_CARD)
    private String idCard;

    private String city;


}

5.创建注解Desensitization

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
//@Target用于限制自定义注解可以应用于哪些程序元素
//ElementType.FIELD:可以应用于字段、枚举常量声明。
@JacksonAnnotationsInside
//作用是将一组注解合并到一个新的注解中。当这个新注解被应用到类或字段上时,实际上相当于应用了它所包含的所有注解。
@JsonSerialize(using = DesensitizationSerialize.class)
//用于自定义 Java 对象如何序列化成 JSON 格式
public @interface Desensitization {
    /**
     * 脱敏数据类型,只要在CUSTOMER的时候,startInclude和endExclude生效
     */
    DesensitizationTypeEnum type() default DesensitizationTypeEnum.CUSTOMER;

    /**
     * 开始位置(包含)
     */
    int startInclude() default 0;

    /**
     * 结束位置(不包含)
     */
    int endExclude() default 0;
}

6.controller

@RestController
@RequestMapping("/test")
public class TestApi {

    @GetMapping("/test-annotation")
    public TestAnnotationDTO testAnnotation(){
        TestAnnotationDTO testAnnotationDTO = new TestAnnotationDTO();
        testAnnotationDTO.setPhone("18336208150");
        testAnnotationDTO.setCustom("2222222222222222");
        testAnnotationDTO.setEmail("1723977647@qq.com");
        testAnnotationDTO.setIdCard("411727199810018533");
        testAnnotationDTO.setCity("郑州城市");
        return testAnnotationDTO;
    }

}

 7.结果

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值