01
—
现状分析
现今个人信息频繁被盗卖情况日益频发,不法份子肆意滥用用户数据,窃取用户信息,进而导致用户财产受损。
目前这种现象已经成为当下的重要安全隐患。随着国家对个人信息数据安全的重视,不断出台多种政策确保个人信息不会被泄露。同时也推动各个公司重视用户的个人信息保护。因此,在非必要获取用户或者用于展示用户信息的时候要做数据掩码处理,是常用的技术处理。
数据定义
数据脱敏(Data Masking),又称数据漂白、数据去隐私化或数据变形。指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。
常见脱敏对象包括但不限于:姓名、身份证号、生日、手机号、具体地址、邮箱、账户,密码等。
02
—
使用前提
本次仅针对使用java开发语言基于spring开发框架的应用项目的日志脱敏输出的解决方案。
1)是否可恢复:
2) 是否动态脱敏:
03
—
通过针对手机号,身份证等指定匹配规则,对所有输出的日志做正则匹配,进而做进一步的脱敏转化。
•优点:可全部网罗脱敏内容,应用无须任何改动;
•缺点:cpu消耗大,有误处理情况;
•使用场景:日志量小,日志信息大都牵扯敏感信息;
通过定义工具类方法,针对不同的数据,提供不同的脱敏输出方案。
•优点:可精确处理具体的敏感信息,处理方式多样化
•缺点:代码日志输出修改量大,且无法网罗全部敏感信息
•使用场景:敏感信息较少
经过综合对比,我们提取了常用日志输出方案一和方案二的优点形成了第三种方案。
本方案通过对需要处理的对象打标记,设立处理方式,使用JsonSerializer的扩展接口,实现标记数据的处理,同时通过扩展logger方法,降低原应用代码的改造。
特点:可针对具体对象的各自属性做针对性的注解标记
04
—
本方案的技术,围绕以下3点,进行整合处理:
脱敏工具
建立丰富的数据多样化工具处理集SensitiveUtils,可针对不同数据,按照不同要求处理,避免使用正则全部匹配。
对象标注
针对应用数据传递处理大多都是基于对象数据格式在处理,通过在对象的属性上标记此数据为敏感数据,是哪种类型,可做到对象数据的统一处理。
扩展slf4j的原生接口
在原有的接口上追加traceMark, infoMark, maskWarn, maskError 让应用开发者能以低成本的修改,即可针对性使用日志脱敏,也可批量替换。
有了这3种的互补配合,在极大的减少应用的使用和改造成本,通过在对象上添加注解,即不破坏原有代码,又能做到针对性数据的脱敏方式。同时通过批量查找修改将原有的log.level调整为log.levelMark。
那这又是怎么做到的呢?
05
—
脱敏工具类就是针对手机号,姓名,身份证,地址,文本等提供不同的脱敏方法。这种不再累赘。
通过查看应用启动后,在应用中使用的logger对象可知,logger对象来自于Log4jLogger,同时实现接口LocationAwareLogger而Log4jLogger 是由我们的Log4jLoggerFactory 类的newLogger创建,因此我们创建自己的Log4jLogger2 继承自 Log4jLogger, 同时让 newLogger 方法去new Log4jLogger2 对象即可。
前提:因spring默认采用jackson作为序列化器,因此本示例基于jackson的注解标记扩展处理。
1)创建@SensitiveMaskField注解
注解在程序中起到标记的作用,就犹如给物品打标签表明此物品所具有的特性,执行代码器会依据此标签查找符合执行的对象。序列化工具采用JackSon的扩展序列化接口。
2) 定义枚举值
定义枚举值,将定义的枚举值对应到具体的工具类方法上
3)创建SensitiveMaskDataSerializer对象处理属性
@SensitiveField标记的属性的处理器,我们采用Jackson的序列化扩展接口JsonSerialize,创建自己的标记识别执行器SensitiveMaskDataSerializer 继承JsonSerializer父类类。
public class SensitiveMaskDataSerializer extends JsonSerializer implements ContextualSerializer
JackSon在处理序列化对象时,会根据标记特性,查找属性上标记的执行器,将对象的实际控制处理交给处理器执行。
以下是处理流程图:
说明:此种标记处理,就可以通过Jackson在序列化对象时,将其中脱敏数据处理掉,其它无关数据不受影响,也不会被脱敏扫描。
MDC - Mapped Diagnostic Context 映射调试上下文,是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。此处用于判断是否需要日志打印脱敏使用。
4. 扩展slf4j接口增加额外的掩码处理方法
扩展方法的好处:
不会破坏原有的日志格式体,应用的改造可随时逐步逐渐的部分替换。
扩展方法与原有对应Level的方法入参一致。因此,也可全量替换
比如:logger.info(** -> logger.maskInfo(**将org.slf4j.Logger接口复制一份,放入本项目中,包名采用org.slf4j不变,用于覆盖原有的Logger接口。
同理将org.apache.logging.slf4j.Log4jLogger复制一份,追加掩码处理方法,原有方法不变。
日志脱敏对原有的org.slf4j.Logger接口扩充脱敏方法,以下为示例扩充方法。
|
|
|
|
|
|
|
|
|
|
我们可对传入方法中的所有String数据,采用统一的文本处理格式,调用统一的处理工具类方法,比如:3个显示3个隐藏。
输入示例:
log.maskInfo("就在北京市十五届人大五次会议闭幕"); log.maskInfo("北京今日标题:{}, {}", "稳住农业基本盘做好三农工作", "巩固拓展脱贫攻坚成果");
输出结果:
就在北***五届人大***议闭幕
北京今日标题:稳住农***盘做好三***, 巩固拓***攻坚成果
对于传入的非String数据的对象类型,为防止数据在非脱敏下使用jackson序列化时被脱敏,因此添加日志的线程变量标记MDC(Mapped Diagnostic Context 映射调试上下文,是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。),SensitiveMaskDataSerializer对数据转化判断MDC标记内容处理数据,脱敏处理日志完成后,移除MDC线程变量标记。
流程处理逻辑:
示例效果:
输入信息:
UserDto user = new UserDto(); user.setName("张三"); user.setPhone("1380000138"); log.info("input User:{}", userDto);
输出结果:
input User:{"name":"张*","phone":"138****0138"}
06
—
最后
💯本方案整体优点:
数据精准处理,减少对正则表达式依赖,取消全盲扫,降低cpu消耗,提升系统整体响应时间。
数据处理结构方式多样,可针对不同数据要求,做不同的处理。
业务代码可渐进式调整,或直接整体调整,修改成本低。