一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

京东云开发者
• 阅读 159

1.tony框架背景

  • 在业务量日益剧增的背景下,大量数据在各种业务活动中产生,数据安全控制一直是治理的重要环节,数据脱敏属于安全控制的范畴。对互联网公司来说,数据安全一直是极为重视和敏感的话题。数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。涉及客户安全数据或者一些商业性敏感数据,如身份证号、手机号、卡号、客户号等个人信息按照相关部门规定,都需要进行数据脱敏。

  • 在现有的微服务技术架构背景下,敏感数据的使用存在如下痛点:

    • 敏感数据与PC、APP客户端使用明文数据交互,数据安全无法保证。

    • 敏感数据浏览缺乏监控,无法针对性的做数据治理。

    • 微服务架构系统应用多而杂,期望引入一套通用的方案统一解决敏感数据安全问题。

基于以上痛点,tony提供了一套完整、安全、透明化、低改造成本的数据脱敏整合解决方案。

2.tony框架简介

Tony是一款敏感数据脱敏与浏览记录监控工具,可对系统中的敏感信息进行脱敏处理,并在泄漏时提供追溯依据,为企业数据共享、迁移、分发提供安全保护措施。该项目基于spring进行开发,提供spring-boot-starter启动包,接入简单,主要实现功能如下:

灵活的脱敏方案

业务系统的数据千变万化,为确保所有业务数据都能够正常进行敏感信息处理,数据脱敏提供高灵活性的自定义脱敏配置。通过丰富多样的脱敏规则定义,敏感数据处理可实现高度契合业务的脱敏处理。

统一的明文数据管理

框架内置敏感数据对应的明文数据管理流程,将明文数据统一缓存管理,提供统一的明文数据访问api。

浏览记录留痕

针对不同用户对敏感信息明文数据的浏览动作,接入方可以自定义日志格式模版记录输出到日志文件中,做到每条数据的浏览有迹可循。

异常浏览量预警

接入方通过自定义脱敏配置可以设置不同场景的敏感浏览明文数据量阈值,开启告警后,当用户访问明文数据次数到达阈值后,会触发预警流程,接入方可自定义预警逻辑。

tony整体架构:

tony-core模块定义了基本的脱敏功能实现,整体流程采用spi机制预留了充分的扩展空间。以tony-core为底座,集成汽车现有技术栈提供了tony-transformers模块对基础的脱敏功能进行了扩展:异步的缓存事件分发,分布式明文数据缓存,对接集团安全部门的敏感日志留痕,异常浏览量的邮件预警。

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

name desc
MaskAnnotationProcessor 业务场景代理,通过注解代理对应的脱敏场景方法。
IMaskProcess 数据脱敏处理器
IMaskLogProcessor 数据浏览日志处理器
IMaskCacheProcessor 明文数据缓存处理器
IMaskLimitProcessor 明文数据访问限额管理
IMaskWarningProcessor 异常浏览预警处理
IMaskContent 上下文信息处理器
IUnMaskProcessor 明文数据获取处理器
DefaultUnMaskProcessorAdapter 明文数据获取适配器,提供从缓存中获取明文数据功能。
DefaultMaskCacheProcess 明文数据缓存处理器,提供分布式缓存功能。
DefaultMaskContent 上下文信息处理器,提供ThreadLocal实现。
DefaultMaskWarningProcessor 异常浏览预警处理,提供邮件告警实现。
PlaintextProcess 明文属于获取接口约束,可自定义明文数据获取的扩展。
MaskMonitorCacheHandle 缓存时间消费,异步消费缓存事件,存储明文数据。

tony处理流程详解:

tony和业务代码部署在一起,接入应用通过脱敏场景与脱敏配置项的指定来实现对应业务场景的脱敏代理。业务代码只需配置场景注解即可兼容使用。此时敏感数据的脱敏工作由tony负责,tony会拦截业务场景的响应数据,对敏感信息进行脱敏处理。

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

tony脱敏配置详解:

脱敏配置主要分为四部分:脱敏上下文配置,脱敏场景配置,脱敏预警配置以及日志留痕模版,其详情如下图所示:

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

key name desc
tony.appName 接入系统名称
tony.maskSourceName 脱敏白名单 控制统一场景的接口对不同调用方进行数据是否脱敏控制
tony.mask.XXX 脱敏场景 XXX为具体场景的key
tony.mask.XXX.enable 动态开关 控制是否开启脱敏
tony.mask.XXX.limits 明文浏览限额 限制明文浏览次数
tony.mask.XXX.cacheKey 数据缓存解析规则 示例:STATEMENT_BILL_PAGE:${argItem.id}
tony.types.YYY 脱敏字段 YYY为具体字段的key
tony.types.YYY.regex 脱敏规则配置 脱敏的正则表达式 示例:(\d{3})\d{4}(\d{4})
tony.types.YYY.replacement 脱敏规则配置 脱敏的正则表达式 示例:$1****$2
tony.types.YYY.logName 日志字段名称

3. 系统详细设计

3.1 详细设计

3.1.1 活动图

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

3.1.2 时序图

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

3.1.3 类图

一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队

职责
com.jd.car.tony.annoation 注解层 负责声明要被代理的业务操作。
com.jd.car.tony.limit 负责记录敏感数据的访问次数,并提供预警。
com.jd.car.tony.mask 管理基础配置,并根据配置进行敏感数据遮盖脱敏。
com.jd.car.tony.log 记录敏感数据的访问操作,输出统一格式的日志信息。
com.jd.car.tony.unmask 提供敏感数据的明文信息查看功能。
com.jd.car.tony.support util包,负责全局功能的支持。

4. 接入使用

4.1 引入坐标

            <dependency>
                <groupId>com.jd.car</groupId>
                <artifactId>tony-spring-boot-starter</artifactId>
                <version>1.8-RELEASE</version>
            </dependency>


4.2 yaml配置

tony:
  appName: "appName"
  #鉴权信息key
  sessionName: ""
  systemName: "systemName"
  warningName: "XXX"
  #脱敏白名单
  maskSourceName: ""
  types:
    name:
      regex: "([\\u4e00-\\u9fa5a-z0-9]{1})[\\u4e00-\\u9fa5a-z0-9]+"
      replacement: "$1**"
      logName: "accountName"
  mask:
    order:
      enable: true
      limits: 100
      limitError: false
      cacheKey: "order:${argItem.id}"
      menuName: "场景名称"
      name: "order"
      #日志记录操作类型
      maskLogOp: ""
      maskLogAccountType: 3

   #预警邮箱设置
   mail:
    mailHost: 
    mailPort: 
    mailUser: 
    mailPwd: 
    mailFrom: 
    mailTo: 
    copyto: 
    sendFlag: 

 #异步事件缓存明文数据配置,分布式缓存
 jd:
  cache:
    jimdb:
      enable: false
      url: ''
  event:
    enable: true
    queue:
      # 自定义queue名字,例如monitorQueue
      maskMonitorQueue:
        retryCount: 3
        maxBakSize: 1000
        # monitorHandle 处理事件的beanName
        handlerBean: maskMonitorCacheHandle 


4.3 日志文件配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <contextName>demo</contextName>
    <!-- 日志最大的历史 单位:天 -->
    <property name="maxHistory" value="90"/>

    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8:00} -%5p ${PID:- } --- [%X{PFTID}][%t] %-40.40logger{39}[%L] : %m%n"/>

    <property name="LOG_CHARSET" value="UTF-8"/>

    <property name="LOG_DES_PATTERN" value="%msg%n" />

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>

    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS,GMT+8:00} -%5p ${PID:- } --- [%X{PFTID}][%t] %-40.40logger{39}[%L] : %m%n"/>

    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%X{PFTID}][%15.15t]){faint} %clr(%-40.40logger{39}[%L]){cyan} %clr(:){faint} %m%n}"/>


    <appender name="mask" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/today_log/mask.log</file>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/history_logs/mask-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <charset>${LOG_CHARSET}</charset>
            <pattern>${LOG_DES_PATTERN}</pattern>
        </encoder>
    </appender>
    <logger name="com.jd.car.tony.log.DefaultMaskLogProcessor" additivity="false">
        <level value="INFO" />
        <appender-ref ref="mask" />
    </logger>

</configuration>


4.3 场景接入

 /**
     * 测试脱敏
     *
     * @return
     */
    @RequestMapping("test")
    @MaskMethod("order")
    public DemoResult test(AuthInfoBO authInfo) {
        return new DemoResult();
    }

    /**
     * 测试脱敏
     *
     * @return
     */
    @RequestMapping("test-list")
    @MaskMethod("order")
    public List<DemoResult> testList(AuthInfoBO authInfo) {
        List<DemoResult> objects = Lists.newArrayList();
        objects.add(new DemoResult());
        objects.add(new DemoResult());
        return objects;
    }

         @Autowired
    private IUnMaskProcessor unMaskProcessorProxy;

    /**
     * 测试反脱敏
     *
     * @return
     */
    @RequestMapping("unmask")
    public Map testUnMask(@RequestBody UnMaskRequest unMaskRequest, AuthInfoBO authInfo) {
        return unMaskProcessorProxy.unMask(unMaskRequest, authInfo);
    }


4.3 脱敏字段配置

@Data
public class DemoResult {

    @Mask(type = "name")
    private String userName = "jajajaasjcij";

    @Mask(type = "phone")
    private String userTel = "18911112222";

    private Long orderId = 1L;

}


4.4 业务监控

业务监控点 触发逻辑
敏感数据明文查看 单账号、单日、单接口访问次数到达访问限额时,则发送邮件给权限管理人员。
敏感数据查询日志 敏感数据脱敏后、明文数据查看时,按集团要求格式单独记录到日志文件中。

作者:京东零售 邱新达

来源:京东云开发者社区

点赞
收藏
评论区
推荐文章
Easter79 Easter79
2年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Easter79 Easter79
2年前
springboot2之优雅处理返回值
前言最近项目组有个老项目要进行前后端分离改造,应前端同学的要求,其后端提供的返回值格式需形如{"status":0,"message":"success","data":{}}方便前端数据处理。要实现前端同学这个需求,其实也挺简单的,
Stella981 Stella981
2年前
Kerberos无约束委派的攻击和防御
 0x00前言简介当ActiveDirectory首次与Windows2000Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身份验证并需要授权用户更新后端数据库服务器上的记录的方案。这通常被称为Kerberosdoublehopissue(双跃点问题),
Wesley13 Wesley13
2年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
Oracle汉字用户名数据脱敏长度不变,rpad函数使用
信息安全考虑,有时需要对用户名称进行数据脱敏。针对Oracle数据库,进行取数数据脱敏处理脱敏规则:长度小于9个字符,只保留前3个汉字与后3个汉字,中间全部由\填充。长度9个字及以上及奇数,隐去中间3个字;长度10个字及以上及奇数,隐去中间4个字。例如:公司名称:宇宙无敌厉害的超级大公司的杭州分公司 字段长度:18脱敏后:
Stella981 Stella981
2年前
JPA项目多数据源模式整合Sharding
引言前一篇博文,已经完整的介绍了数据库脱敏的场景及方案,来自京东数科的ShardingJDBC开源项目通过对数据源中间代理的方式透明化的实现了这个功能,但是,功能虽然实现了,sql兼容的小问题还是很多,比如目前不支持子查询,数据库定义的关键字不允许使用,等等问题,反观我们需要加解密的字段,其实相比业务的sql来说占比非常小,即使遇
Wesley13 Wesley13
2年前
Java日志脱敏框架 sensitive
项目介绍日志脱敏是常见的安全需求。普通的基于工具类方法的方式,对代码的入侵性太强。编写起来又特别麻烦。本项目提供基于注解的方式,并且内置了常见的脱敏方式,便于开发。特性基于注解的日志脱敏。可以自定义策略实现,策略生效条件。常见的脱敏内置方案。java深拷贝
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
京东云开发者 京东云开发者
10个月前
Hutool:一行代码搞定数据脱敏 | 京东云技术团队
本文主要介绍了数据脱敏的相关内容,首先介绍了数据脱敏的概念,在此基础上介绍了常用的数据脱敏规则;随后介绍了本文的重点Hutool工具及其使用方法,在此基础上进行了实操,分别演示了使用DesensitizedUtil工具类、配合Jackson通过注解的方式完成数据脱敏;最后,介绍了一些常见的数据脱敏方法,并附上了对应的教程链接供大家参考,本文内容如有不当之处,还请大家批评指正。