preface

Data desensitization refers to deforming some sensitive information through desensitization rules to achieve reliable protection of sensitive privacy data. The requirement is to desensitize the data returned to the front end so as not to leak private information.


First, the effect of desensitization

That’s a bad display, isn’t it? Everything’s out thereSo that’s good

Second, the code

1. Desensitization notes

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerialize.class)
public @interface Sensitive {

    /** * Desensitization data type */
    SensitiveTypeEnum type(a) default SensitiveTypeEnum.CUSTOMER;

    /** ** does not need to type the code length */
    int prefixNoMaskLen(a) default 0;

    /** ** does not need to type the length of the code */
    int suffixNoMaskLen(a) default 0;

    /**
     * 用什么打码
     */
    String symbol(a) default "*";
}
Copy the code

2. Define desensitization types

public enum SensitiveTypeEnum {
    /** * Custom */
    CUSTOMER,
    /** * name */
    NAME,
    /** * id */
    ID_NUM,
    /** * Mobile phone number */
    PHONE_NUM
}
Copy the code

3. Sensitive tool classes

public class DesensitizedUtils {

    /** * desensitize the string ** @param Origin the original string * @param prefixNoMaskLen needs to keep several plaintext fields * @param suffixNoMaskLen needs to keep several plaintext fields * @param maskStr Mask string, such as '*' * @return desensitization result */
    public static String desValue(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
        if (origin == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0, n = origin.length(); i < n; i++) {
            if (i < prefixNoMaskLen) {
                sb.append(origin.charAt(i));
                continue;
            }
            if (i > (n - suffixNoMaskLen - 1)) {
                sb.append(origin.charAt(i));
                continue;
            }
            sb.append(maskStr);
        }
        return sb.toString();
    }

    /** ** only the last Chinese character is displayed, other hidden asterisks, such as: ** dream ** @param fullName name * @return result */
    public static String chineseName(String fullName) {
        if (fullName == null) {
            return null;
        }
        return desValue(fullName, 1.0."*");
    }

    /** * [ID number] display the first 4 digits, the last 2 digits, other hidden. * * @param ID ID * @return Result */
    public static String idCardNum(String id) {
        return desValue(id, 4.2."*");
    }

    /** * [mobile phone number] the first three, the last four, other hidden. * * @param num Mobile phone number * @return Result */
    public static String mobilePhone(String num) {
        return desValue(num, 3.4."*"); }}Copy the code

4. Desensitize and serialize information

@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {

    /** * desensitization type */
    private SensitiveTypeEnum sensitiveTypeEnum;

    /** ** the first few do not desensitize */
    private Integer prefixNoMaskLen;

    /** ** ** /
    private Integer suffixNoMaskLen;

    /**
     * 用什么打码
     */
    private String symbol;

    @Override
    public void serialize(final String origin, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider) throws IOException {
        switch (sensitiveTypeEnum) {
            case CUSTOMER:
                jsonGenerator.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, symbol));
                break;
            case NAME:
                jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
                break;
            case ID_NUM:
                jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
                break;
            case PHONE_NUM:
                jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
                break;
            default:
                throw new IllegalArgumentException("unknown sensitive type enum "+ sensitiveTypeEnum); }} @Override
    publicJsonSerializer<? >createContextual(final SerializerProvider serializerProvider,
                                              final BeanProperty beanProperty) throws JsonMappingException {
        if(beanProperty ! = null) {if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
                if (sensitive == null) {
                    sensitive = beanProperty.getContextAnnotation(Sensitive.class);
                }
                if(sensitive ! = null) {return newSensitiveSerialize(sensitive.type(), sensitive.prefixNoMaskLen(), sensitive.suffixNoMaskLen(), sensitive.symbol()); }}return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        returnserializerProvider.findNullValueSerializer(null); }}Copy the code

conclusion

This annotation is used to desensitize private data and only applies to class attributes. This annotation has four attributes. Type indicates the desensitized data type (customized by CUSTOMER by default), prefixNoMaskLen indicates the length that does not need to be pre-typed (default: 0), suffixNoMaskLen indicates the length that does not need to be pre-typed (default: 0), and suffixNoMaskLen indicates the length that does not need to be pre-typed (default: 0). Symbol indicates what to type (the default is *). Generally used to return the object to the front-end object contains private data such as ID card, detailed address need to be desensitized.

Example:

public class UserInfo {

    @Sensitive(type = SensitiveTypeEnum.NAME)
    private String name;

    @Sensitive(type = SensitiveTypeEnum.ID_NUM)
    private String idNum;

    @Sensitive(type = SensitiveTypeEnum.PHONE_NUM)
    private String phone;

    @Sensitive(type = SensitiveTypeEnum.CUSTOMER, prefixNoMaskLen = 3, suffixNoMaskLen = 2, symbol = "#")
    private String address;

    @Sensitive(prefixNoMaskLen = 1, suffixNoMaskLen = 2, symbol = "*")
    private String password;
}
Copy the code

If you have any questions I wrote a demo, you can download it and run it and see the link: Desensitization Notes Demo.