网易首页 > 网易号 > 正文 申请入驻

Hutool:一行代码搞定数据脱敏

0
分享至

来源 | OSCHINA 社区

作者 | 京东云开发者-京东科技 孙扬威

原文链接:https://my.oschina.net/u/4090830/blog/10094536

1. 什么是数据脱敏1.1 数据脱敏的定义

数据脱敏百度百科中是这样定义的:

数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。是数据库安全技术之一。

总的来说,数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。

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

1.2 常用脱敏规则

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

2. Hutool 工具介绍2.1 引入 Maven 配置

在项目的 pom.xml 的 dependencies 中加入以下内容,这里以 5.8.16 版本为例。


cn.hutoolgroupId>
hutool-allartifactId>
5.8.16version>
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 脱敏是通过 * 来代替敏感信息的,具体实现是在 StrUtil.hide 方法中,如果我们想要自定义隐藏符号,则可以把 Hutool 的源码拷出来,重新实现即可 。

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

importcn.hutool.core.util.DesensitizedUtil;
importorg.junit.Test;
importorg.springframework.boot.test.context.SpringBootTest;

/**
*
* @description: Hutool实现数据脱敏
*/
@SpringBootTest
publicclassHuToolDesensitizationTest{

@Test
publicvoidtestPhoneDesensitization(){
String phone="13723231234";
System.out.println(DesensitizedUtil.mobilePhone(phone));//输出:137****1234
}
@Test
publicvoidtestBankCardDesensitization(){
String bankCard="6217000130008255666";
System.out.println(DesensitizedUtil.bankCard(bankCard));//输出:6217 **** **** *** 5666
}

@Test
publicvoidtestIdCardNumDesensitization(){
String idCardNum="411021199901102321";
//只显示前4位和后2位
System.out.println(DesensitizedUtil.idCardNum(idCardNum,4,2));//输出:4110************21
}
@Test
publicvoidtestPasswordDesensitization(){
String password="www.jd.com_35711";
System.out.println(DesensitizedUtil.password(password));//输出:****************
}
}

以上就是使用 Hutool 封装好的工具类实现数据脱敏。

3.2 配合 JackSon 通过注解方式实现脱敏

现在有了数据脱敏工具类,如果前端需要显示数据数据的地方比较多,我们不可能在每个地方都调用一个工具类,这样就显得代码太冗余了,那我们如何通过注解的方式优雅的完成数据脱敏呢?

如果项目是基于 springboot 的 web 项目,则可以利用 springboot 自带的 jackson 自定义序列化实现。它的实现原来其实就是在 json 进行序列化渲染给前端时,进行脱敏。

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


* @author
* @description:脱敏策略枚举
publicenumDesensitizationTypeEnum{
//自定义
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生效
DesensitizationTypeEnumtype()defaultDesensitizationTypeEnum.MY_RULE;

/**
* 脱敏开始位置(包含)
*/
intstartInclude()default0;

/**
* 脱敏结束位置(不包含)
*/
intendExclude()default0;
}

注:只有使用了自定义的脱敏枚举 MY_RULE 的时候,开始位置和结束位置才生效。

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

这一步是我们实现数据脱敏的关键。自定义序列化类继承 JsonSerializer,实现 ContextualSerializer 接口,并重写两个方法。


* @author
* @description: 自定义序列化类
@AllArgsConstructor
@NoArgsConstructor
publicclassDesensitizationSerializeextendsJsonSerializer implementsContextualSerializer{
privateDesensitizationTypeEnum type;

privateInteger startInclude;

privateInteger endExclude;

@Override
publicvoidserialize(String str,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)throwsIOException{
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
publicJsonSerializer createContextual(SerializerProvider serializerProvider,BeanProperty beanProperty)throwsJsonMappingException{
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,开始位置,结束位置。
returnnewDesensitizationSerialize(desensitization.type(), desensitization.startInclude(),
desensitization.endExclude());
}
}

return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
return serializerProvider.findNullValueSerializer(null);
}
}

经过上述三步,已经完成了通过注解实现数据脱敏了,下面我们来测试一下。

首先定义一个要测试的 pojo,对应的字段加入要脱敏的策略。


* @description:
@Data
@NoArgsConstructor
@AllArgsConstructor
publicclassTestPojo{

privateString userName;

@Desensitization(type =DesensitizationTypeEnum.MOBILE_PHONE)
privateString phone;

@Desensitization(type =DesensitizationTypeEnum.PASSWORD)
privateString password;

@Desensitization(type =DesensitizationTypeEnum.MY_RULE, startInclude =0, endExclude =2)
privateString address;
}

接下来写一个测试的 controller

@RestController
publicclassTestController{

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

}

 可以看到我们成功实现了数据脱敏。

4. 其他常见的数据脱敏工具推荐

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

4.1 Apache ShardingSphere

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

具体实现方式可参考下面文章: https://jaskey.github.io/blog/2020/03/18/sharding-sphere-data-desensitization/

4.2 FastJSON

平时开发 Web 项目的时候,除了默认的 Spring 自带的序列化工具,FastJson 也是一个很常用的 Spring web Restful 接口序列化的工具。

FastJSON 实现数据脱敏的方式主要有两种:

  • 基于注解 @JSONField 实现:需要自定义一个用于脱敏的序列化的类,然后在需要脱敏的字段上通过 @JSONField 中的 serializeUsing 指定为我们自定义的序列化类型即可。

  • 基于序列化过滤器:需要实现 ValueFilter 接口,重写 process 方法完成自定义脱敏,然后在 JSON 转换时使用自定义的转换策略。具体实现可参考这篇文章: https://juejin.cn/post/7067916686141161479

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 提供的如下代码: https://gitee.com/baomidou/mybatis-mate-examples

5. 总结

本文主要介绍了数据脱敏的相关内容,首先介绍了数据脱敏的概念,在此基础上介绍了常用的数据脱敏规则;随后介绍了本文的重点 Hutool 工具及其使用方法,在此基础上进行了实操,分别演示了使用 DesensitizedUtil 工具类、配合 Jackson 通过注解的方式完成数据脱敏;最后,介绍了一些常见的数据脱敏方法,并附上了对应的教程链接供大家参考,本文内容如有不当之处,还请大家批评指正。

6. 参考内容

Hutool 工具官网: https://hutool.cn/docs/#/?id=%f0%9f%93%9a%e7%ae%80%e4%bb%8b

聊聊如何自定义数据脱敏: https://juejin.cn/post/7046567603971719204

FastJSON 实现数据脱敏: https://juejin.cn/post/7067916686141161479

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
高考结束后,你是怎样放纵的?网友:当晚把全班男生送进了牢里

高考结束后,你是怎样放纵的?网友:当晚把全班男生送进了牢里

特特农村生活
2024-06-12 08:11:47
日本专家:在中国生活什么都好,就是有一样东西只有中国能给

日本专家:在中国生活什么都好,就是有一样东西只有中国能给

苗苗情感说
2024-06-14 07:50:02
商务部副部长王受文:中国光伏、新能源汽车等产品不存在产能过剩

商务部副部长王受文:中国光伏、新能源汽车等产品不存在产能过剩

新京报
2024-06-13 19:34:22
笑不活了!清华学霸爷爷送孙女高考接受采访,我却笑死在了评论区

笑不活了!清华学霸爷爷送孙女高考接受采访,我却笑死在了评论区

天气观察站
2024-06-12 15:03:28
U20亚洲杯预选赛分组出炉,中国作为东道主无需参加

U20亚洲杯预选赛分组出炉,中国作为东道主无需参加

直播吧
2024-06-13 17:05:20
1962年,河南共产主义渠宣告失败,原因是什么,死了多少人

1962年,河南共产主义渠宣告失败,原因是什么,死了多少人

老黄有话
2024-06-13 14:18:52
中国出口吉尔吉斯斯坦新能源客车订单完成全批次交付

中国出口吉尔吉斯斯坦新能源客车订单完成全批次交付

北青网-北京青年报
2024-06-13 20:05:04
凯特全身插满管子的高清照片流出!不露面是因为行动不便,起不来

凯特全身插满管子的高清照片流出!不露面是因为行动不便,起不来

亦纯杂谈
2024-06-13 10:58:45
曾经大火的油混汽车,为啥一下子就败给插混?内行人道破,知晓了

曾经大火的油混汽车,为啥一下子就败给插混?内行人道破,知晓了

娱乐圈的笔娱君
2024-06-13 15:52:56
38岁已婚女与37岁情人,在石凳子上发生关系,温存后被残忍杀害

38岁已婚女与37岁情人,在石凳子上发生关系,温存后被残忍杀害

胖胖侃咖
2024-06-08 08:00:08
过分了,南京一医院血液科办开业仪式被骂上热搜,评论区炸锅

过分了,南京一医院血液科办开业仪式被骂上热搜,评论区炸锅

今日养生之道
2024-06-13 01:41:48
撒贝宁一家四口开豪华房车,千岛湖露营,网友:像卡车一样带劲

撒贝宁一家四口开豪华房车,千岛湖露营,网友:像卡车一样带劲

柠檬有娱乐
2024-06-11 09:50:38
我认识的有钱人现在也都不消费了,他们不消费的原因一个比一个扎心

我认识的有钱人现在也都不消费了,他们不消费的原因一个比一个扎心

好笑娱乐君每一天
2024-06-12 07:35:02
84岁大爷自学参加高考,估分630四处张扬,成绩出来后不敢相信!

84岁大爷自学参加高考,估分630四处张扬,成绩出来后不敢相信!

华人星光
2024-06-13 14:34:51
欧盟宣布加征关税后 特拉斯计划提高Model 3在欧洲售价

欧盟宣布加征关税后 特拉斯计划提高Model 3在欧洲售价

财联社
2024-06-13 20:18:24
内衣上做标记发现女友出轨,网友直呼福尔摩斯!

内衣上做标记发现女友出轨,网友直呼福尔摩斯!

听风听你
2024-06-12 22:05:36
方昊晒国足比赛照:这是我第一次参加世界杯预选赛

方昊晒国足比赛照:这是我第一次参加世界杯预选赛

懂球帝
2024-06-14 06:36:09
又一国宣布出手,否认南海属于中方领土,中方恐提前打响第一枪!

又一国宣布出手,否认南海属于中方领土,中方恐提前打响第一枪!

绝对军评
2024-06-13 07:50:08
淘汰希洪竞技,西班牙人晋级西乙升级附加赛决赛

淘汰希洪竞技,西班牙人晋级西乙升级附加赛决赛

直播吧
2024-06-14 06:57:10
等不及了!解放军退役老艇长,单刀赴台,回来要被处罚这值得吗?

等不及了!解放军退役老艇长,单刀赴台,回来要被处罚这值得吗?

近史博览
2024-06-13 14:35:48
2024-06-14 09:02:44
开源中国
开源中国
每天为开发者推送最新技术资讯
6324文章数 34225关注度
往期回顾 全部

科技要闻

马斯克:明年千台人形机器人在特斯拉上班

头条要闻

亲绿网红在大陆旅游称"真的很喜欢这里" 气得绿营跳脚

头条要闻

亲绿网红在大陆旅游称"真的很喜欢这里" 气得绿营跳脚

体育要闻

乔丹最想单挑的男人走了

娱乐要闻

森林北报案,称和汪峰的感情遭受压力

财经要闻

私募大佬孙强:中国为什么缺少耐心资本

汽车要闻

升级8155芯片 新款卡罗拉锐放售12.98-18.48万

态度原创

房产
健康
数码
旅游
公开课

房产要闻

再度告急!海口连续仨月住宅入市不足千套!竟有楼盘卖爆!

晚餐不吃or吃七分饱,哪种更减肥?

数码要闻

三星 Galaxy Watch 首款 FE 产品正式发布,199 美元起

旅游要闻

山西文旅厅厅长与董宇辉拉家常:中午回家吃了饭

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版