一种配置化的数据脱敏与反脱敏框架实现 | 京东云技术团队
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 业务监控
业务监控点 | 触发逻辑 |
---|---|
敏感数据明文查看 | 单账号、单日、单接口访问次数到达访问限额时,则发送邮件给权限管理人员。 |
敏感数据查询日志 | 敏感数据脱敏后、明文数据查看时,按集团要求格式单独记录到日志文件中。 |
作者:京东零售 邱新达
来源:京东云开发者社区

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
万字长文浅析配置对MySQL服务器的影响 | 京东物流技术团队
有很多的服务器选项会影响这MySQL服务器的性能,比如内存中临时表的大小、排序缓冲区等。有些针对特定存储引擎(如InnoDB)的选项,也会对查询优化很有用。 调整服务器的配置从某种程度来说是一个影响全局的行为,因为每个修改都可能对该服务器上的每个查询造成影响。不过有些选项是针对特定类型的优化的,如果你的请求没有满足条件,它将没有任何作用。 首先我们需要检查的选项是缓冲区大小(buffer size) 每个缓冲区都有其存在的特定原因,一般的规律是大缓冲区意味着高性能,不过仅当请求可以针对该缓冲区扮演的特定角色使用大容量缓存的时候。 当然,增加缓冲区大小是有代价的,下面是一些大缓冲区可能带来的影响。 •交换区 大容量缓冲区可能会导致会使用到操作系统级别的交换区从而造成性能缓慢,这取决于系统内存大小。通常情况下,MySQL服务器在它所需的所有内存都来自物理内存的时候运行最快。当它使用到交换区的时候,性能显著下降。 当为缓冲区分配的内存大小超过服务器的物理内存大小的时候就会使用到交换区。有一些缓冲区是针对每个用户线程的。要确定这些缓冲区究竟需要多少内存,可以用公式 max_connection...
- 下一篇
618技术揭秘 - 大促弹窗搭投实践 | 京东云技术团队
背景 618 大促来了,对于业务团队来说,最重要的事情莫过于各种大促营销。如会场、直播带货、频道内营销等等。而弹窗作为一个极其重要的强触达营销工具,通常用来渲染大促氛围、引流主会场、以及通过频道活动来提升频道复访等。因此,如果能将运营的策略及想法快速转化为弹窗的内容并触达给用户,这对于提升运营效率及玩法灵活性的是极其有意义的。 此前,在 JD 主站的大多弹窗业务应用中,XView 仅仅是作为一个 h5 的容器被使用,或基于 XView 提供的一些简单的配置化能力来配置一个弹窗。作为 h5 容器的方式虽然灵活,但需要研发的参与。而基于 XView 提供的配置化能力,虽然只需产品、运营侧配置,但是配置化逻辑繁琐、学习成本高、且对于弹窗样式有局限,不够灵活。因此,此前使用的俩种方式,弊端都可以归结为:使用成本高。 为了持续优化XView 性能, XView 从配置化的方式,升级为组件化搭建的方式,以一种更加直观的可视化拖拽元素组件搭建弹窗样式,而后附加投放的配置,其目标便是解决此前所面临的几个重点问题: •学习成本高 •不够灵活 •需要编码 升级完成后,本次 618 的一些重要弹窗均迁移到全...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8安装Docker,最新的服务器搭配容器使用