【数据安全】数据脱敏方案总结

本文涉及的产品
数据安全中心,免费版
简介: 【数据安全】数据脱敏方案总结

【数据安全】数据脱敏方案总结
1.数据脱敏概述
2.常用数据脱敏规则
3.常用数据脱敏方法
Hutool
配合 JackSon 通过注解方式实现脱敏
通过Apache ShardingSphere
通过FastJson
通过MyBatis-Mate
通过MyBatis-Flex
1.数据脱敏概述
数据脱敏,指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。这样就可以在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。是数据库安全技术之一

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

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

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

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

用户 id
中文姓名
身份证号
座机号
手机号
地址
电子邮件
密码
中国大陆车牌,包含普通车辆、新能源车辆
银行卡
配合 JackSon 通过注解方式实现脱敏
如果项目是基于 Spring Boot 的 web 项目,则可以利用 Spring Boot 自带的 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
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1、定义一个用于脱敏的 Desensitization 注解

@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;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注:只有使用了自定义的脱敏枚举 MY_RULE 的时候,开始位置和结束位置才生效。

2、创建自定的序列化类

自定义序列化类继承 JsonSerializer,实现 ContextualSerializer 接口,并重写两个方法

@AllArgsConstructor
@NoArgsConstructor
public class DesensitizationSerialize extends JsonSerializer 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);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
已经完成了通过注解实现数据脱敏了,下面我们来测试一下

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

@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;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
4、接下来写一个测试的 controller

@RestController
public class TestController {

@RequestMapping("/test")
public TestPojo testDesensitization(){
    TestPojo testPojo = new TestPojo();
    testPojo.setUserName("我是用户名");
    testPojo.setAddress("地球中国-北京市海淀区度小满总部");
    testPojo.setPhone("13111111111");
    testPojo.setPassword("123456789jajaja");
    System.out.println(testPojo);
    return testPojo;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
成功实现了数据脱敏

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

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

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

官方文档地址:

https://shardingsphere.apache.org/document/4.1.1/cn/features/orchestration/encrypt/

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

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

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

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

配置内容如下:

Mybatis Mate 配置

mybatis-mate:
cert:
grant: jxftsdfggggx
license: GKXP9r4MCJhGID/DTGigcBcLmZjb1YZGjE4GXaAoxbtGsPC20sxpEtiUr2F7Nb1ANTUekvF6Syo6DzraA4M4oacwoLVTglzfvaEfadfsd232485eLJK1QsskrSJmreMnEaNh9lsV7Lpbxy9JeGCeM0HPEbRvq8Y+8dUt5bQYLklsa3ZIBexir+4XykZY15uqn1pYIp4pEK0+aINTa57xjJNoWuBIqm7BdFIb4l1TAcPYMTsMXhF5hfMmKD2h391HxWTshJ6jbt4YqdKD167AgeoM+B+DE1jxlLjcpskY+kFs9piOS7RCcmKBBUOgX2BD/JxhR2gQ==
1
2
3
4
5
具体实现可以参考:https://gitee.com/baomidou/mybatis-mate-examples

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

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

用户名脱敏
手机号脱敏
固定电话脱敏
身份证号脱敏
车牌号脱敏
地址脱敏
邮件脱敏
密码脱敏
银行卡号脱敏
使用案例:

@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;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
如果这些内置的脱敏规则不满足你的要求的话,你还可以自定义脱敏规则。
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/Gherbirthday0916/article/details/140378725

目录
相关文章
|
1月前
|
数据安全/隐私保护 数据格式
数据安全必备:三种实用的数据脱敏技术
在数字化时代,数据安全和隐私保护成为了企业和个人关注的焦点。数据脱敏作为一种有效的数据保护手段,能够降低数据泄露的风险,保护用户隐私。本文将介绍三种常见的数据脱敏方案,帮助您在实际工作中选择合适的脱敏技术。
142 2
|
2月前
|
自然语言处理 算法 Unix
【数据安全】敏感字过滤方案总结
【数据安全】敏感字过滤方案总结
54 1
|
3月前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【9月更文挑战第11天】在数字时代,数据安全至关重要。AES与RSA加密技术相结合,构成了一道坚固防线。AES以其高效性保障数据加密,而RSA则确保密钥安全传输,二者相辅相成,提供双重保护。本文通过Python代码示例展示了这一加密方案的魅力,强调了其在实际应用中的重要性和安全性。使用HTTPS等安全协议传输加密密钥和密文,确保数据在数字世界中自由流通而无忧。
83 1
|
4月前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【8月更文挑战第3天】在数字时代,数据安全至关重要。Python AES+RSA加密方案提供了一种强大且可靠的数据保护方式。AES以高效安全著称,适用于大量数据的快速加密;RSA作为非对称加密技术,确保了密钥传输的安全性。二者结合形成“内外兼修”的加密策略:AES加密数据内容,RSA保护AES密钥,共同构建起数据安全的双重保险。通过示例代码展示了这一加密流程,强调了加密后密钥与密文的安全传输和存储的重要性。在实际应用中,应采用HTTPS等安全协议进行传输,并将数据安全存储于加密的数据库或文件系统中。
89 12
|
7月前
|
安全 算法 数据管理
数据安全产品之认识数据脱敏系统
数据脱敏是一种信息安全技术,它通过将敏感信息转换成无实际意义的数据,同时保持原始数据的格式、类型和业务逻辑,以确保数据在使用过程中的安全性和合规性。数据脱敏的目的是保护个人隐私和企业敏感信息,防止数据在非生产环境中泄露或被不当使用。
218 0
|
运维 算法 安全
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——4. 特色研发能力
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——4. 特色研发能力
368 1
|
存储 数据采集 供应链
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——卷首语
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——卷首语
281 0
|
存储 安全
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——一、数据建设与治理的现状与诉求
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——一、数据建设与治理的现状与诉求
159 0
|
运维 分布式计算 监控
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——1. 用中台方法论构建与治理企业级好数据概览
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——1. 用中台方法论构建与治理企业级好数据概览
508 0
|
数据建模 供应链 定位技术
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——2. 规划:高屋建瓴,总览企业数据体系
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——2. 规划:高屋建瓴,总览企业数据体系
242 0