# data-desensitized **Repository Path**: shellay/data-desensitized ## Basic Information - **Project Name**: data-desensitized - **Description**: 解决系统中数据安全问题,可以对Json类型的请求做数据脱敏及针对日志内容做数据脱敏。可自定义敏感信息,对原系统侵入性较小,提供多种可扩展方法。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-07-20 - **Last Updated**: 2023-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 数据脱敏(DD-desensitized data) #### 背景 伴随着技术的发展,互联网的触角已经融入到生活中的每个角落,各种各样的App记录着我们的日常生活点滴。经历过技术的野蛮生长,个人信息满天飞的时代,诈骗、勒索等犯罪事件越来普遍,随之而来的是人们对隐私和信息安全的呼声越来越强烈。 在系统中,人的行为可以理解成`"人对资源的操作"`,就期目标而言,信息安全可以分成两个层次: - 操作层面 > 操作的动作,如:查询,修改,添加,删除等。 - 数据安全 > 操作的资源,各种各样的信息数据,如,个人电话、住址等信息 #### 目标 本项目属于数据安全层面的一个补充,通过对敏感信息加密,即便数据泄露后,敏感数据信息不可读,减少因数据泄露而产生的负面影响。 #### 软件介绍 软件以SpringBoot为技术基础,从API和日志两层面对敏感数据进行加密脱敏。核心设计思想是在Json与对象间转换时,对敏感内容进行干预,**注意**本软件是基于`Jackson`进行设计。 - API: > Restful风格且基于Json的API,在序列化与序列化过程中对指定的敏感信息进行编码与解码。 - 日志 > 日志基于log4j,对日志中的敏感内容进行编码脱敏。 #### 使用说明 ##### 初始配置 1. Maven依赖 ```xml com.yy.tech.data desensitized-data 1.0-SNAPSHOT ``` 2. 在Application或是Configuration类上加注解`@EnableDesensitization`,或是`@ComponentScan`把包扫描到SpringBean容器中。如: ```java @SpringBootApplication @EnableDesensitization public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } } ``` 3. 本软件提供了一个默认的Bean`desensitizeObjectMapper`,如果已有自定义的`ObjectMapper`,可以调用`DesensitizeHelper.help(ObjectMapper mapper)`方法,为`ObjectMapper`追加脱敏相关配置。 ```java @Configuration @ComponentScan @ConditionalOnProperty(value = SecretContent.KEY_DESENSITIZE_ENABLE,havingValue = "true") public class DesensitizedConfiguration { @Autowired private DesensitizeHelper helper; @Bean(SecretContent.DESENSITIZE_OBJECT_MAPPER) @ConditionalOnMissingBean(name = SecretContent.DESENSITIZE_OBJECT_MAPPER) public ObjectMapper desensitizeObjectMapper(){ return helper.help(); } } ``` *如果没有生效,可能需要为`HttpMessageConverter`手动设置一下`ObjectMapper`。* ##### 自定义敏感规则 1. 注解方式 - @SecretProperty > 在Restful API中,对Request或是Response中的敏感内容加上该注解,在请求过程中会对该属性进行编码和解码。可在SecretProperty指定`Encoder`和`Decoder`. - @SecretParam > 在Restful API中,主要用于对URL中的参数进行解码。 2. Json文件方式 > 支持通过配置方式配置脱敏规则。具体配置属性可参见`SecretRules`和`SecretRule`. 3. 环境变量方式 > 可以通过环境变量配置脱敏规则。 #### Example *完整示例可参见`desensitized-app`* ##### 测试API - 基于Bean实体 URI: >`{{host}}/data/demo/bean` Request: ```json { "title": "desensitized", "employee": { "name": "test1", "idType": "sfz", "idNumber": "111333532524525", "email": "example@tech.com", "phone": "18801233210" } } ``` Response: ```json { "employee": { "name": "test1", "birthdate": null, "idType": "{AES}bxjufniPS4dJSzntcDIkzw==", "idNumber": "{AES}Je/0qCbn2oF87WjyEjJwKQ==", "phone": "18801233210", "address": null, "updateTime": null } } ``` - 基于Map URI: > {{host}}/data/demo/map Request: ```json { "title": "desensitized", "employee": { "name": "test1", "idType": "sfz", "idNumber": "111333532524525", "email": "example@tech.com", "phone": "18801233210" } } ``` Response: ```json { "title": "desensitized", "employee": { "name": "test1", "idType": "{AES}bxjufniPS4dJSzntcDIkzw==", "idNumber": "111333532524525", "email": "example@tech.com", "phone": "18801233210" }, "employeeId": -7760358248143830538, "idNumber": "310122199907121234", "updateTime": "2022-08-24 21:34:46" } ``` - 基于参数 URI: > {{host}}/data/demo/para/{AES}bxjufniPS4dJSzntcDIkzw== Response: ```json { "employee": { "name": "Example path variable", "birthdate": "1999-03-12", "idType": "{AES}muV/ZmvmHc7Q4lh/JDT6MQ==", "idNumber": "{AES}bxjufniPS4dJSzntcDIkzw==", "phone": "18817881788", "address": null, "updateTime": "2022-09-21 21:41:08" } } ``` ##### 相关配置 1、环境配置 ```yaml spring: jackson: date-format: yyyy-MM-dd HH:mm:ss desensitize: enable: true//是否激活数据敏感,当为false时,不会对敏感内容编码 encoder: AES256Encoder//AES256编码器 mask_encoder://掩码类型编码相关配置,主要用于日志 len: 12 mode: 0 char: "#" decoder: AES256Decoder//AES256解码器 secret: properties: idType//敏感属性,多个可用','分隔 excludes: email//排除属性,即在Response中移除 resource://规则配置文件相关 dir: desensitized post: "*.json" logger: properties: idType,idNumber//日志敏感属性,多个可用','分隔 encoder: MaskEncoder//指定日志编码器 excludes: customerId//日志中不显示属性 ``` 2. Json配置文件 ```json { "rules": [ { "encrypts": ["idNumber"], "excludes": ["employeeId"] } ] } ``` ##### 日志配置 日志配置有两种方式,只支持在Logger中直接输出对象,基础类型无法脱敏。 1、Properties指定messageFactory > 在项目resources目录下加一个`log4j2.component.properties`配置文件 ```properties log4j2.messageFactory=com.yy.tech.data.logger.message.DesensitizedParameterizedMessageFactory ``` 2. log4j2配置pattern > 把默认的msg->smsg ```xml [%d{yyyy-MM-dd HH:mm:ss.SSS}][%-5p][%T][%c.%M:%L] %smsg%xEx%n ``` ##### 编码解码器 1. AES256 AES256Encoder/AES256Decoder 2. Base64 BASE64Encoder/BASE64Decoder 3. Mask掩码(主要应用于日志)MaskEncoder 扩展时,需要分别实现Encoder或是Decoder接口,如 编码: ```java @Component(SecretContent.ENCODER_BASE64) class Base64Encoder extends StdConverter implements Encoder { @Autowired private Base64Secret secret; @Override public String convert(final String str) { return secret.encrypt(str); } } @Component(SecretContent.ENCODER_AES256) class Aes256Encoder extends StdConverter implements Encoder{ @Autowired private Aes256Secret secret; @Override public String convert(final String s) { return secret.encrypt(s); } } ``` 解码 ```java @Component(SecretContent.DECODER_BASE64) class Base64Decoder extends StdConverter implements Decoder { @Autowired private Base64Secret secret; @Override public String convert(final String str) { return secret.decrypt(str); } } @Component(SecretContent.DECODER_AES256) class Aes256Decoder extends StdConverter implements Decoder { @Autowired private Aes256Secret secret; @Override public String convert(final String str) { return secret.decrypt(str); } } ``` ##### 如何自定义编码解码器 1. 在环境参数中指定,全局 2. 在`@SecretProperty`或是`@SecretParam`中指定,可具体到属性 3. 在规则配置文件中指定