数据去敏

一、背景

利用注解,反射,正则实现对象属性数据的去敏操作

二、实现

package com.hk.study.annotation;


import com.hk.study.constant.EncryptedType;

import java.lang.annotation.*;

/**
 * 敏感数据模糊处理
 *
 * @author bigbeardhk
 */
@Retention(RetentionPolicy.RUNTIME) // 注解可以反射获取
@Target(ElementType.FIELD) // 注解只能打在成员属性上
@Documented
public @interface Encrypted {
    EncryptedType encryptedType();
}

/**
 * Copyright (c) bigbeardhk@163.com Corporation 2022. All Rights Reserved.
 */

package com.hk.study.util;

import com.hk.study.annotation.Encrypted;
import com.hk.study.constant.EncryptedType;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 对实例对象的简单处理
 *
 * @Author : bigbeardhk
 * @Date : 2022/05/04 16:23
 **/
public class BeanUtil {


    /**
     * 数据去敏 - 对实例对象属性的去敏处理
     *
     * @param obj 需要处理的对象
     * @throws IllegalAccessException 反射异常
     */
    public static <T> void setDefaultDataByRead(T obj) throws IllegalAccessException {
        // 获取父类及子类的所有成员变量
        List<Field> allField = new ArrayList<>();
        allField.addAll(Arrays.asList(obj.getClass().getDeclaredFields()));
        allField.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields()));
        // 循环所有属性
        for (Field field : allField) {
            field.setAccessible(true);
            // 查找使用标记@Encrypted注解的属性
            if (field.getAnnotation(Encrypted.class) != null) {
                // field.get(obj)为该属性值
                if (field.get(obj) != null) {
                    String value = null;
                    if (field.get(obj) instanceof String) {
                        value = (String) field.get(obj);
                    }
                    // 注解打在非String类型的属性上时,就不会进这个方法
                    if (value != null) {
                        // 若取出对应的为加密字段,就根据相对应的标识进行加密处理(应该抽取出来)
                        Encrypted encrypted = field.getAnnotation(Encrypted.class);
                        EncryptedType encryptedType = encrypted.encryptedType();
                        if (encryptedType == EncryptedType.NAME) {
                            if (value.length() == 2) {
                                field.set(obj, value.replaceAll(".(?=[\\u4e00-\\u9fa5])","*" ));
                            } else if (value.length() > 2) {
                                field.set(obj, value.replaceAll("(?<=[\\u4e00-\\u9fa5]).(?=[\\u4e00-\\u9fa5])", "*"));
                            }
                        } else {
                            field.set(obj, value.replaceAll(encryptedType.getCode(),
                                    encryptedType.getValue()));
                        }
                    }
                }
            }
        }
    }
}

/**
 * Copyright (c) bigbeardhk@163.com Corporation 2022. All Rights Reserved.
 */

package com.hk.study.vo.validator;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.hk.study.annotation.Encrypted;
import com.hk.study.constant.EncryptedType;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Author : bigbeardhk
 * @Date : 2022/05/01 19:51
 **/
@Data
@ApiModel(value = "UserAO" , description = "用户模型")
public class UserEncrypted {
    @Encrypted(encryptedType = EncryptedType.NAME)
    @ApiModelProperty(value = "姓名")
    private String name;

    @Encrypted(encryptedType = EncryptedType.PHONE_NUMBER)
    @ApiModelProperty(value = "手机号")
    private String phone;

    @Encrypted(encryptedType = EncryptedType.ID_CARD_NUMBER)
    @ApiModelProperty(value = "身份证")
    private String idCard;

    public UserEncrypted() {
    }

    public UserEncrypted(String name, String phone, String idCard) {
        this.name = name;
        this.phone = phone;
        this.idCard = idCard;
    }
}

package com.hk.study.constant;

import lombok.Getter;

/**
 * 数据去敏
 *
 * @author bigbeardhk
 */
@Getter
public enum EncryptedType {
    // 身份证号码(18位)
    ID_CARD_NUMBER("(\\d{4})\\d{10}(\\d{3}([\\d|x|X]{1})$)", "$1**********$2"),
    // 姓名
    NAME("(\\d{1}).*(\\d{1})", "$1*$2"),
    // 手机号码
    PHONE_NUMBER("(\\d{3})\\d{6}(\\d{2})", "$1******$2");

    private String code;
    private String value;

    EncryptedType(String code, String value) {
        this.code = code;
        this.value = value;
    }
}

结果:
image.png

posted @ 2022-05-04 16:44  JerryMouseJDK  阅读(41)  评论(0编辑  收藏  举报