数据脱敏方案总结

news/2024/10/22 21:19:50/

什么是数据脱敏

数据脱敏的定义

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

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

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

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

常用脱敏规则

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

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

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

常用脱敏工具

Hutool

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

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

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

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

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

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

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

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

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

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

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

第二步:定义一个用于脱敏的 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;
    }

    第三步:创建自定的序列化类
    这一步是我们实现数据脱敏的关键。自定义序列化类继承 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;}}

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

    Apache ShardingSphere

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

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

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

    官方文档地址:数据脱敏 :: ShardingSphere


http://www.ppmy.cn/news/1541156.html

相关文章

[图形学]蒙特卡洛积分方法介绍及其方差计算

一、简介 本文介绍了蒙特卡洛积分算法的基本原理和其误差计算。 二、蒙特卡洛积分介绍 1. 介绍 蒙特卡洛积分算法是一种数值积分算法&#xff0c;用于对复杂函数进行积分。 例如&#xff0c;对于目标积分函数&#xff1a; ∫ a b f ( x ) d x (1) \int_{a}^{b}f(x)\rm{d}x…

MongoDB文档的详细使用说明

以下是关于MongoDB文档的详细使用说明&#xff1a; 1. 文档的概念 文档是MongoDB中数据的基本单元&#xff0c;它是一个类似于JSON格式的键值对数据结构&#xff0c;也被称为BSON&#xff08;Binary JSON&#xff09;格式。文档可以包含不同类型的数据字段&#xff0c;并且可…

Android 10.0 Camera2 拍照镜像功能实现

1.前言 在10.0的系统rom定制化开发中,在进行camera2的相关拍照功能开发中,在某些时候会遇到拍照照片 左右镜像的问题,就是照片左半边和右半边是反的,所以就需要在拍照的时候保存图片的时候实现 左右镜像功能,接下来就来分析下拍照保存图片的流程 2.Camera2 拍照镜像功能实…

15分钟学Go 第6天:变量与常量

第6天&#xff1a;变量与常量 在Go语言中&#xff0c;变量和常量是编程的基础概念。理解如何定义和使用它们不仅能帮助我们管理数据&#xff0c;还能增强代码的可读性和可维护性。在本章中&#xff0c;我们将详细探讨Go语言中的变量和常量&#xff0c;涵盖它们的定义、使用、作…

Python 工具库每日推荐 【sqlparse】

文章目录 引言SQL解析工具的重要性今日推荐:sqlparse工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:SQL查询分析器案例分析高级特性自定义格式化处理多个语句扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScript 设计模式 专栏…

录微课专用提词器,不会被录进视频中的提词器,还能显示PPT中备注的内容

不坑提词器&#xff0c;全称&#xff1a;不坑隐形提词器。是一款能够在截图、录屏、直播过程中隐藏界面的提词器软件。 系统要求&#xff1a;Win10 1024 以上&#xff08;特别提醒&#xff1a;Win7状态下不可隐身&#xff09; ⏬下载 提词器默认放在不坑盒子的安装目录下&…

嵌套元素的“事件”冒泡?!——WEB开发系列52

事件处理是创建交互式用户界面的关键部分&#xff0c;浏览器通过事件系统让我们能够捕获和响应用户的输入&#xff0c;比如点击、鼠标移动、键盘输入等。 什么是事件冒泡&#xff1f; 事件冒泡是指在嵌套的 HTML 元素中&#xff0c;一个事件从最具体的元素开始&#xff0c;然后…

Leetcode 二叉搜索树的第 K 个元素

复习一下二叉搜索树 二叉搜索树 (Binary Search Tree, 简称 BST) 是一种特殊的二叉树(可以为空)&#xff0c;其中每个节点都有一个值&#xff0c;并且满足以下特点&#xff1a; 定义&#xff1a; 左子树节点的值小于根节点的值&#xff1a;对于每个节点&#xff0c;左子树中所…