Custom annotations to achieve data desensitization, national secret encryption and decryption (sm4)

Custom annotations to achieve data desensitization, national secret encryption and decryption (sm4)
often encounters some situations in actual development that some information cannot be displayed to users, and part of it needs to be hidden (can be called desensitization), such as address, phone number, mobile phone number , ID card, etc.
Desensitization methods Currently I know the following methods:
1): Business code desensitization: As the name implies, the field that needs to be desensitized after getting the data is entered into a series of desensitization rules and replaced with the format you want.
2): The method of custom annotation + aop aspect is used to complete the purpose of field desensitization.
3): Desensitize data by custom annotation + serialization.
Among them, the slowest efficiency is the code business code method, and the optimal method is the custom annotation method, which reduces the amount of code and improves work efficiency. The fields that need desensitization only need to add one annotation to achieve the goal.
Record the third way today, the way of custom annotation + serialization.
First define a strategy that requires desensitization


/**
 * @description: 脱敏策略
 * @author: 
 * @date: 2023/6/18 19:45
 * @Version: 1.0
 */
public enum DesensitizationEnum {

    /**
     * 名称脱敏
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2"))
    ,
    /**
     * 手机号脱敏
     */
    MOBILE_PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"))
    ,
    /**
     *地址脱敏
     */
    ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"))
    ;

    /**
     * 成员变量  是一个接口类型
     */
    private Function<String, String> function;

    DesensitizationEnum(Function<String, String> function) {
        this.function = function;
    }

    public Function<String, String> function() {
        return this.function;
    }
}

Then customize an annotation

import com.chaozhou.test01.dingShiRenWu.Annontion.Aspect.DesensitizationEnum;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @description:
 * @author:
 * @date: 2023/6/18 17:23
 * @Version: 1.0
 */

@Target({ElementType.FIELD}) //表明作用在字段上
@Retention(RetentionPolicy.RUNTIME) //什么情况下生效
@JacksonAnnotationsInside //标明序列化
@JsonSerialize(using = DesensitizationDataSerialize.class)
public @interface DesensitizationData {

    DesensitizationEnum function();
}

Then customize a serializer

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.Objects;

/**
 * @description: 数据脱敏序列化器
 * @author: 
 * @date: 2023/6/18 19:17
 * @Version: 1.0
 */
@NoArgsConstructor
public class DesensitizationDataSerialize extends JsonSerializer<String> implements ContextualSerializer {

    private DesensitizationEnum fuincation;

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        DesensitizationData annotation = beanProperty.getAnnotation(DesensitizationData.class);
        if(Objects.nonNull(annotation) && Objects.equals(beanProperty.getType().getRawClass(),String.class)){
            this.fuincation = annotation.function();
            return this;
        }
        return serializerProvider.findValueSerializer(beanProperty.getType(),beanProperty);
    }

    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(fuincation.function().apply(s));
    }

}

Such a custom desensitization annotation is completed.
How to use:
You only need to add response annotations to the fields that need to be desensitized in the return parameters

public class User implements Serializable {

    @TableId("id")
    private Integer id;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    @ApiModelProperty(value = "出生年月")
    private Date birthday;

    @ApiModelProperty(value = "性别")
    private String gender;

    @ApiModelProperty(value = "姓名")
    private String username;

    @ApiModelProperty(value = "密码")
    private String password;

    @ApiModelProperty(value = "备注")
    private String remark;

    @ApiModelProperty(value = "状态")
    private String station;

    @ApiModelProperty(value = "联系电话")
    //手机号脱敏
    @DesensitizationData(function = DesensitizationEnum.MOBILE_PHONE)
    private String telephone;

}

Results
insert image description here
The mobile phone number has been desensitized successfully, and this method supports both single and multiple data.


The dependencies needed for national secret encryption and decryption can be implemented directly with the framework integrated by hutool

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.16</version>
        </dependency>
        <!--以下依赖不加亲测也可以实现-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.60</version>
        </dependency>

Add encryption and decryption rules to the strategy in the above method,
insert image description here
then add the annotation to the field that needs to be encrypted or decrypted, and annotate the correct strategy
insert image description here
to modify the serializer above to prevent the field value that needs to be decrypted when I am empty "Null input buffer" error is reported
insert image description here
before the list field is encrypted
insert image description here

After the list is encrypted
insert image description here

The tools are well prepared, and the code efficiency is much higher.

Guess you like

Origin blog.csdn.net/weixin_51114236/article/details/131276402