java实现敏感数据脱敏

一、自定义注解的方式

(一)创建一个脱敏工具类

package cn.com.citydo.earlywarningsystem.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * 敏感信息脱敏工具类
 * @author shensw
 */
public class MaskUtil {
     

    /**
     * 手机号脱敏
     * @param phone
     * @return
     */
    public final static String maskPhone(String phone){
     
        if(phone==null || phone.length()!=11) {
     
            return phone;
        }
        return StringUtils.join(phone.substring(0,3)+"******"+phone.substring(9));
    }

    /**
     * 身份证号脱敏
     * @param id
     * @return
     */
    public final static String maskIdCard(String id){
     
        if(id==null || id.length()!=18) {
     
            return id;
        }
        return StringUtils.join(id.substring(0,6)+"****");
    }

    /**
     *中文姓名脱敏
     * @param fullName
     * @return
     */
    public final static String chineseName(String fullName) {
     
        if(StringUtils.isBlank(fullName)) {
     
            return fullName;
        }
        String name = StringUtils.left(fullName, 1);
        return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
    }

    /**
     *家庭住址脱敏
     * @param address
     * @param sensitiveSize 敏感信息长度
     * @return
     */
    public final static String address(String address, int sensitiveSize) {
     
        if(StringUtils.isBlank(address)) {
     
            return address;
        }
        int length = StringUtils.length(address);
        return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length - sensitiveSize+4, "*");
    }

    /**
     *邮箱脱敏
     * @param email
     * @return
     */
    public final static String email(String email) {
     
        if (StringUtils.isBlank(email)) {
     
            return email;
        }
        int index = StringUtils.indexOf(email, "@");
        if(index <= 1) {
     
            return email;
        } else {
     
            return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));
        }
    }

    /**
     *银行卡号脱敏
     * @param cardNum
     * @return
     */
    public final static String bankCard(String cardNum) {
     
        if(StringUtils.isBlank(cardNum)) {
     
            return cardNum;
        }
        return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
    }

    /**
     *固定电话脱敏
     * @param num
     * @return
     */
    public final static String fixedPhone(String num) {
     
        if(StringUtils.isBlank(num)) {
     
            return num;
        }
        return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
    }
}

(二) 编写自定义注解

package cn.com.citydo.earlywarningsystem.aspect;

import java.lang.annotation.*;
/**
 * @Author yangxi
 * @Date 2020/1/6 10:53
 * 脱敏信息注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SensitiveField {
     

    SensitiveTypeEnum value() default SensitiveTypeEnum.IDCARD;

    enum SensitiveTypeEnum {
     
        IDCARD,
        PHONE,
        NAME,
        ADDRESS,
    }

}

(三)重写用于toString的ReflectionToStringBuilder

package cn.com.citydo.earlywarningsystem.configure;

import cn.com.citydo.earlywarningsystem.aspect.SensitiveField;
import cn.com.citydo.earlywarningsystem.utils.MaskUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.lang.reflect.Field;

/**
 * @Author yangxi
 * @Date 2020/1/7 10:26
 * 重写用于toString的ReflectionToStringBuilder
 */
public class SensitiveReflectionToStringBuilder extends ReflectionToStringBuilder {
     

    public SensitiveReflectionToStringBuilder(Object object, ToStringStyle style) {
     
        super(object, style);
    }

    @Override
    protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
     
        if (field.getType() == String.class && field.isAnnotationPresent(SensitiveField.class)) {
     
            String v = (String) field.get(this.getObject());
            switch (field.getAnnotation(SensitiveField.class).value()) {
     
                case IDCARD:
                    return MaskUtil.maskIdCard(v);
                case PHONE:
                    return MaskUtil.maskPhone(v);
                case NAME:
                    return MaskUtil.chineseName(v);
                case ADDRESS:
                    //TODO
                    return MaskUtil.address(v, StringUtils.length(v));
                default:
                    return v;
            }
        }
        return field.get(this.getObject());
    }

}

(四) 对需要脱敏的数据,在对应的实体类属性里加上自定义脱敏注解

package cn.com.citydo.earlywarningsystem.entity.vo;

import cn.com.citydo.earlywarningsystem.aspect.SensitiveField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;

/**
 * @Author yangxi
 * @Date 2020/1/5 16:54
 * 信访登记显示列表
 */
@Data
public class LettersVisitVO {
     
    @ApiModelProperty("信访信息主键id")
    private Integer visitId;

    @SensitiveField(SensitiveField.SensitiveTypeEnum.NAME)
    @ApiModelProperty("投诉人姓名")
    private String complainantName;

    @ApiModelProperty("被投诉名称")
    private String respondentName;

    @ApiModelProperty("被投诉人用工地址")
    private String respondentAddress;

    @SensitiveField(SensitiveField.SensitiveTypeEnum.NAME)
    @ApiModelProperty("被投诉联系人")
    private String respondentContacts;

    @ApiModelProperty("被投诉人职务")
    private String respondentJob;

    @SensitiveField(SensitiveField.SensitiveTypeEnum.PHONE)
    @ApiModelProperty("被投诉人电话")
    private String respondentPhone;

    @ApiModelProperty("投诉时间")
    private Date dealTime;

    @ApiModelProperty("指派(下达至)区域编号")
    private Integer assignRegion;

}

二、 用遍历的方式对需要脱敏的数据使用自定义的工具类实现脱敏

(一) 自定义脱敏工具类

package cn.com.citydo.earlywarningsystem.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * 敏感信息脱敏工具类
 * @author shensw
 */
public class MaskUtil {
     

    /**
     * 手机号脱敏
     * @param phone
     * @return
     */
    public final static String maskPhone(String phone){
     
        if(phone==null || phone.length()!=11) {
     
            return phone;
        }
        return StringUtils.join(phone.substring(0,3)+"******"+phone.substring(9));
    }

    /**
     * 身份证号脱敏
     * @param id
     * @return
     */
    public final static String maskIdCard(String id){
     
        if(id==null || id.length()!=18) {
     
            return id;
        }
        return StringUtils.join(id.substring(0,6)+"****");
    }

    /**
     *中文姓名脱敏
     * @param fullName
     * @return
     */
    public final static String chineseName(String fullName) {
     
        if(StringUtils.isBlank(fullName)) {
     
            return fullName;
        }
        String name = StringUtils.left(fullName, 1);
        return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
    }

    /**
     *家庭住址脱敏
     * @param address
     * @param sensitiveSize 敏感信息长度
     * @return
     */
    public final static String address(String address, int sensitiveSize) {
     
        if(StringUtils.isBlank(address)) {
     
            return address;
        }
        int length = StringUtils.length(address);
        return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length - sensitiveSize+4, "*");
    }

    /**
     *邮箱脱敏
     * @param email
     * @return
     */
    public final static String email(String email) {
     
        if (StringUtils.isBlank(email)) {
     
            return email;
        }
        int index = StringUtils.indexOf(email, "@");
        if(index <= 1) {
     
            return email;
        } else {
     
            return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));
        }
    }

    /**
     *银行卡号脱敏
     * @param cardNum
     * @return
     */
    public final static String bankCard(String cardNum) {
     
        if(StringUtils.isBlank(cardNum)) {
     
            return cardNum;
        }
        return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
    }

    /**
     *固定电话脱敏
     * @param num
     * @return
     */
    public final static String fixedPhone(String num) {
     
        if(StringUtils.isBlank(num)) {
     
            return num;
        }
        return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
    }
}

(二)使用lambda表达式对需要的数据进行脱敏

    public PageInfo queryVisitor(String keyWork, String assignRegion, PageHelperEntity pageHelperEntity, Date complaintStartDate, Date complaintEndDate) {
     
        PageUtil.startPage(pageHelperEntity);
        List<LettersVisitVO> visitVOList = visitMapper.queryVisitor(keyWork, assignRegion, complaintStartDate, complaintStartDate);

        visitVOList.stream().forEach(
                m -> {
     
                     m.setComplainantName(MaskUtil.chineseName(m.getComplainantName()));
                     m.setRespondentContacts(MaskUtil.chineseName(m.getRespondentContacts()));
                     m.setRespondentPhone(MaskUtil.maskPhone(m.getRespondentPhone()));

                }
        );

        PageInfo<LettersVisitVO> pageInfo = new PageInfo<>(visitVOList);

        return pageInfo;
    }

你可能感兴趣的:(MyBatis)