java实现敏感数据脱敏

  • Post author:
  • Post category:java




一、自定义注解的方式



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

import org.apache.commons.lang3.StringUtils;

/**
 * 敏感信息脱敏工具类
 */
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), "*");
    }
}



(二) 编写自定义注解


import java.lang.annotation.*;
/**
 * @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


/**
 * @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());
    }

}



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


@Data
public class LettersVisitVO {
    @ApiModelProperty("信访信息主键id")
    private Integer visitId;

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

}



二、 直接调用工具类对字段进行脱敏



版权声明:本文为weixin_43777379原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。