1. 什么是数据脱敏

1.1 数据脱敏的界说

数据脱敏百度百科中是这样界说的:

数据脱敏,指对某些灵敏信息经过脱敏规矩进行数据的变形,完成灵敏隐私数据的牢靠保护。这样就能够在开发、测验和其它非生产环境以及外包环境中安全地运用脱敏后的实在数据集。在触及客户安全数据或者一些商业性灵敏数据的情况下,在不违背系统规矩条件下,对实在数据进行改造并供给测验运用,如身份证号、手机号、卡号、客户号等个人信息都需求进行数据脱敏。是数据库安全技能之一。

总的来说,数据脱敏是指对某些灵敏信息经过脱敏规矩进行数据的变形,完成灵敏隐私数据的牢靠保护。

在数据脱敏过程中,通常会选用不同的算法和技能,以根据不同的需求和场景对数据进行处理。例如,关于身份证号码,能够运用掩码算法(masking)将前几位数字保存,其他位用“X”或”*”替代;关于名字,能够运用假造(pseudonymization)算法,将实在名字替换成随机生成的化名。

1.2 常用脱敏规矩

替换、重排、加密、截断、掩码

2. Hutool东西介绍

2.1 引进Maven装备

在项目的pom.xml的dependencies中参加以下内容,这儿以5.8.16版别为例。

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>

留意 :Hutool 5.x支撑JDK8+, 如果你的项目运用JDK7,请运用Hutool 4.x版别。本文运用的数据脱敏东西类只要在5.6+版别以上才供给。

2.2 Hutool包括的组件

一个Java根底东西类,对文件、流、加密解密、转码、正则、线程、XML等JDK办法进行封装,组成各种Util东西类,同时供给以下组件:

模块 介绍
hutool-aop JDK动态代理封装,供给非IOC下的切面支撑
hutool-bloomFilter 布隆过滤,供给一些Hash算法的布隆过滤
hutool-cache 简略缓存完成
hutool-core 核心,包括Bean操作、日期、各种Util等
hutool-cron 定时使命模块,供给类Crontab表达式的定时使命
hutool-crypto 加密解密模块,供给对称、非对称和摘要算法封装
hutool-db JDBC封装后的数据操作,根据ActiveRecord思维
hutool-dfa 根据DFA模型的多关键字查找
hutool-extra 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)
hutool-http 根据HttpUrlConnection的Http客户端封装
hutool-log 自动识别日志完成的日志门面
hutool-script 脚本履行封装,例如Javascript
hutool-setting 功用更强大的Setting装备文件和Properties封装
hutool-system 系统参数调用封装(JVM信息等)
hutool-json JSON完成
hutool-captcha 图片验证码完成
hutool-poi 针对POI中Excel和Word的封装
hutool-socket 根据Java的NIO和AIO的Socket封装
hutool-jwt JSON Web Token (JWT)封装完成

能够根据需求对每个模块独自引进,也能够经过引进hutool-all办法引进一切模块,本文所运用的数据脱敏东西便是在hutool.core模块。

2.3 Hutool支撑的脱敏数据类型

现阶段最新版别的Hutool支撑的脱敏数据类型如下,根本覆盖了常见的灵敏信息。

1.用户id

2.中文名字

3.身份证号

4.座机号

5.手机号

6.地址

7.电子邮件

8.暗码

9.中国大陆车牌,包括一般车辆、新能源车辆

10.银行卡

3. Hutool数据脱敏实操

3.1 运用Hutool东西类一行代码完成脱敏

Hutool供给的脱敏办法如下图所示:

Hutool:一行代码搞定数据脱敏 | 京东云技术团队

留意 :Hutool 脱敏是经过*来替代灵敏信息的,详细完成是在StrUtil.hide办法中,如果咱们想要自界说隐藏符号,则能够把Hutool的源码拷出来,从头完成即可。

这儿以手机号、银行卡号、身份证号、暗码信息的脱敏为例,下面是对应的测验代码。

import cn.hutool.core.util.DesensitizedUtil;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
 * 
 * @description: Hutool完成数据脱敏
 */
@SpringBootTest
public class HuToolDesensitizationTest {
    @Test
    public void testPhoneDesensitization(){
        String phone="13723231234";
        System.out.println(DesensitizedUtil.mobilePhone(phone)); //输出:137****1234
    }
    @Test
    public void testBankCardDesensitization(){
        String bankCard="6217000130008255666";
        System.out.println(DesensitizedUtil.bankCard(bankCard)); //输出:6217 **** **** *** 5666
    }
    @Test
    public void testIdCardNumDesensitization(){
        String idCardNum="411021199901102321";
        //只显现前4位和后2位
        System.out.println(DesensitizedUtil.idCardNum(idCardNum,4,2)); //输出:4110************21
    }
    @Test
    public void testPasswordDesensitization(){
        String password="www.jd.com_35711";
        System.out.println(DesensitizedUtil.password(password)); //输出:****************
    }
}

以上便是运用Hutool封装好的东西类完成数据脱敏。

3.2 配合JackSon经过注解办法完成脱敏

现在有了数据脱敏东西类,如果前端需求显现数据数据的当地比较多,咱们不可能在每个当地都调用一个东西类,这样就显得代码太冗余了,那咱们怎么经过注解的办法优雅的完成数据脱敏呢?

如果项目是根据springboot的web项目,则能够利用springboot自带的jackson自界说序列化完成。它的完成原来其实便是在json进行序列化渲染给前端时,进行脱敏。

第一步: 脱敏战略的枚举。


/**
 * @author
 * @description:脱敏战略枚举
 */
public enum DesensitizationTypeEnum {
    //自界说
    MY_RULE,
    //用户id
    USER_ID,
    //中文名
    CHINESE_NAME,
    //身份证号
    ID_CARD,
    //座机号
    FIXED_PHONE,
    //手机号
    MOBILE_PHONE,
    //地址
    ADDRESS,
    //电子邮件
    EMAIL,
    //暗码
    PASSWORD,
    //中国大陆车牌,包括一般车辆、新能源车辆
    CAR_LICENSE,
    //银行卡
    BANK_CARD
}

上面表示支撑的脱敏类型。

第二步: 界说一个用于脱敏的 Desensitization 注解。

  • @Retention(RetentionPolicy.RUNTIME):运行时收效。

  • @Target(ElementType.FIELD):可用在字段上。

  • @JacksonAnnotationsInside:此注解能够点进去看一下是一个元注解,主要是用户打包其他注解一起运用。

  • @JsonSerialize:上面说到过,该注解的效果便是可自界说序列化,能够用在注解上,办法上,字段上,类上,运行时收效等等,根据供给的序列化类里边的重写办法完成自界说序列化。

/**
 * @author 
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationSerialize.class)
public @interface Desensitization {
    /**
     * 脱敏数据类型,在MY_RULE的时分,startInclude和endExclude收效
     */
    DesensitizationTypeEnum type() default DesensitizationTypeEnum.MY_RULE;
    /**
     * 脱敏开端方位(包括)
     */
    int startInclude() default 0;
    /**
     * 脱敏完毕方位(不包括)
     */
    int endExclude() default 0;
}

注:只要运用了自界说的脱敏枚举MY_RULE的时分,开端方位和完毕方位才收效。

第三步:创建自定的序列化类

这一步是咱们完成数据脱敏的关键。自界说序列化类承继 JsonSerializer,完成ContextualSerializer接口,并重写两个办法。


/**
 * @author 
 * @description: 自界说序列化类
 */
@AllArgsConstructor
@NoArgsConstructor
public class DesensitizationSerialize extends JsonSerializer<String> implements ContextualSerializer {
    private DesensitizationTypeEnum type;
    private Integer startInclude;
    private Integer endExclude;
    @Override
    public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        switch (type) {
            // 自界说类型脱敏
            case MY_RULE:
                jsonGenerator.writeString(CharSequenceUtil.hide(str, startInclude, endExclude));
                break;
            // userId脱敏
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId()));
                break;
            // 中文名字脱敏
            case CHINESE_NAME:
                jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str)));
                break;
            // 身份证脱敏
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2));
                break;
            // 固定电话脱敏
            case FIXED_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str)));
                break;
            // 手机号脱敏
            case MOBILE_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str)));
                break;
            // 地址脱敏
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str), 8));
                break;
            // 邮箱脱敏
            case EMAIL:
                jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str)));
                break;
            // 暗码脱敏
            case PASSWORD:
                jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str)));
                break;
            // 中国车牌脱敏
            case CAR_LICENSE:
                jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str)));
                break;
            // 银行卡脱敏
            case BANK_CARD:
                jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str)));
                break;
            default:
        }
    }
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            // 判断数据类型是否为String类型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                // 获取界说的注解
                Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);
                // 为null
                if (desensitization == null) {
                    desensitization = beanProperty.getContextAnnotation(Desensitization.class);
                }
                // 不为null
                if (desensitization != null) {
                    // 创建界说的序列化类的实例而且返回,入参为注解界说的type,开端方位,完毕方位。
                    return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(),
                            desensitization.endExclude());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}

经过上述三步,已经完成了经过注解完成数据脱敏了,下面咱们来测验一下。

首先界说一个要测验的pojo,对应的字段参加要脱敏的战略。

/**
 *
 * @description:
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestPojo {
    private String userName;
    @Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)
    private String phone;
    @Desensitization(type = DesensitizationTypeEnum.PASSWORD)
    private String password;
    @Desensitization(type = DesensitizationTypeEnum.MY_RULE, startInclude = 0, endExclude = 2)
    private String address;
}

接下来写一个测验的controller

@RestController
public class TestController {
    @RequestMapping("/test")
    public TestPojo testDesensitization(){
        TestPojo testPojo = new TestPojo();
        testPojo.setUserName("我是用户名");
        testPojo.setAddress("地球中国-北京市通州区京东总部2号楼");
        testPojo.setPhone("13782946666");
        testPojo.setPassword("sunyangwei123123123.");
        System.out.println(testPojo);
        return testPojo;
    }
}

Hutool:一行代码搞定数据脱敏 | 京东云技术团队

能够看到咱们成功完成了数据脱敏。

4. 其他常见的数据脱敏东西引荐

除了本文介绍的Hutool东西之外,还有一些其他的数据脱敏东西,常见脱敏办法或东西如下所示:

4.1 Apache ShardingSphere

Apache ShardingSphere下面存在一个数据脱敏模块,此模块集成的常用的数据脱敏的功用。其根本原理是对用户输入的SQL进行解析拦截,并依靠用户的脱敏装备进行SQL的改写,从而完成对原文字段的加密及加密字段的解密。终究完成对用户无感的加解密存储、查询。

详细完成办法可参阅下面文章: jaskey.github.io/blog/2020/0…

4.2 FastJSON

平常开发Web项目的时分,除了默许的Spring自带的序列化东西,FastJson也是一个很常用的Spring web Restful接口序列化的东西。

FastJSON完成数据脱敏的办法主要有两种:

  • 根据注解@JSONField完成:需求自界说一个用于脱敏的序列化的类,然后在需求脱敏的字段上经过@JSONField中的serializeUsing 指定为咱们自界说的序列化类型即可。

  • 根据序列化过滤器:需求完成ValueFilter接口,重写process办法完成自界说脱敏,然后在JSON转化时运用自界说的转化战略。

详细完成可参阅这篇文章: /post/706791…

4.3 Mybatis-mate

mybatisplus也供给了数据脱敏模块,mybatis-mate,不过在运用之前需求装备授权码。

装备内容如下所示:

# Mybatis Mate 装备
mybatis-mate:
  cert:
    grant: jxftsdfggggx
    license: GKXP9r4MCJhGID/DTGigcBcLmZjb1YZGjE4GXaAoxbtGsPC20sxpEtiUr2F7Nb1ANTUekvF6Syo6DzraA4M4oacwoLVTglzfvaEfadfsd232485eLJK1QsskrSJmreMnEaNh9lsV7Lpbxy9JeGCeM0HPEbRvq8Y+8dUt5bQYLklsa3ZIBexir+4XykZY15uqn1pYIp4pEK0+aINTa57xjJNoWuBIqm7BdFIb4l1TAcPYMTsMXhF5hfMmKD2h391HxWTshJ6jbt4YqdKD167AgeoM+B+DE1jxlLjcpskY+kFs9piOS7RCcmKBBUOgX2BD/JxhR2gQ==

详细完成可参阅baomidou供给的如下代码: gitee.com/baomidou/my…

5. 总结

本文主要介绍了数据脱敏的相关内容,首先介绍了数据脱敏的概念,在此根底上介绍了常用的数据脱敏规矩;随后介绍了本文的要点Hutool东西及其运用办法,在此根底上进行了实操,别离演示了运用DesensitizedUtil东西类、配合Jackson经过注解的办法完成数据脱敏;最终,介绍了一些常见的数据脱敏办法,并附上了对应的教程链接供我们参阅,本文内容如有不当之处,还请我们批评指正。

6. 参阅内容

Hutool东西官网: hutool.cn/docs/#/?id=…

聊聊怎么自界说数据脱敏: /post/704656…

FastJSON完成数据脱敏: /post/706791…

作者:京东科技 孙扬威

来源:京东云开发者社区