大数据如何采集加密日志(Springboot 日志、配置文件、接口数据如何脱敏?这样才叫优雅)

原文:https://mp.weixin.qq.com/s/ieZbTQz7GKiZsJjnw1sekQ

一、前言

核心隐私数据对企业和用户都尤为重要,要想办法防止各种隐私数据的泄露。下面就带大家从以下三个方面来解释一下如何对隐私数据进行脱敏,这也是日常开发中需要注意的事情:

  • 轮廓数据脱敏
  • 接口返回数据脱敏
  • 日志文件数据脱敏
  • 文章目录如下:




    二、配置文件如何脱敏?

    通常情况下,项目的配置文件中总会有一些敏感信息,比如数据源的url、用户名和密码...这些信息一旦暴露,整个数据库都会泄露,那么如何隐藏这些配置呢?

    过去,加密的配置被手动写入配置文件,然后在提取时手动解密。当然这是一个思路,可以解决问题,但是每次都要手动加密解密,不是很麻烦吗?



    今天,我们介绍一个方案,它允许您在不知道的情况下加密和解密配置文件。使用开源插件:jasypt-spring-boot。项目地址如下:

    Https://github.com/ulisesbocchio/jasypt-spring-boot 很容易使用,只需要添加一个启动器就可以集成Spring Boot。

    1. 添加依赖

    & lt依赖性& gt & lt;groupId & gtcom . github . ulisesbocchio & lt;/groupId & gt; & lt;artifactId & gtjas ypt-spring-boot-starter & lt;/artifact id & gt; & lt;版本& gt3 . 0 . 3 & lt;/version & gt; & lt;/dependency & gt; 2。配置密钥将加密密钥(可选)添加到配置文件中,如下所示:

    Jasypt: 加密器: 密码:Y6M9Fajqdu7JNP5mw 当然,直接把密钥放在配置文件里也是不安全的。我们可以在项目开始时配置密钥。该命令如下所示:

    Java-jar XXX . jar-djasypt . encryptor . password = y 6m 9 fajqdu 7 jn p5mw 3。生成加密数据这一步是对配置明文进行加密,代码如下:

    @ springbootest @ run with(spring runner . class) public class springbootasyptapapplicationtests { /* * */ @ /* * *手动生成密文,这里演示url、用户、密码 */ @ test public void encrypt(){[/hJDBC:MySQL://127 . 0 . 0 . 1:3306/test?use unicode = true & character encoding = UTF-8 & zeroDateTimeBehavior = convert null & use SSL = false & allow multiqueries = true & server time zone = Asia/Shanghai & # 34;); String name = encryptor . encrypt(& # 34;根& # 34;); String password = encryptor . encrypt(& # 34;123456"); system . out . println(& # 34;数据库URL:& # 34;+网址); system . out . println(& # 34;数据库名称:& # 34;+姓名); system . out . println(& # 34;数据库密码:& # 34;+密码); assert . assert true(URL . length()& gt;0); assert . assert true(name . length()& gt;0); assert . assert true(password . length()& gt;0); } } 以上代码以明文形式加密数据源的url、用户和密码,输出结果如下:

    数据库URL:szkfdg 56 wcaozg 2g utv 0 m2 oavnfh 5g 3 dxz 0 o 6 jozjt 26y 5 wna+1Z+pqfpyhfboqop2 jsftb+p 9 B3 GB 601 rfas 3d sfvs 8 BGO 3 my P1 nojjgvp 6 gcvi+B/xus 0 ke xpn+pbX/19 hrlun 1 leewehs/lcrzslhwjcsixtwzo 1 lpxv 3 vyhf 2 oezklm 3 miayj 51 crean 3 w5 cmice将加密后的密文写入配置jasypt默认使用enc()包。

    Spring: datasource: #数据源基本配置 用户名:ENC(l 8 I 2 rqyppttnnl 4x 8 vhrvaksudlstgzend/3 tonvtypwe 0 znwsw 0/5 jdus w9 ulm) 密码:ENC(ejycsbbl 8 PMF 2 hubih 7 dhhpfdzclyjcegmr 9 jav 3 apjtvftx 9 tvdhupsaxjq 2 pnj) driver-class-name:com . MySQL

    jaspyt: encrypter: # #指定前缀和后缀 属性: 前缀:& # 39;PASS(& # 39; 后缀:& # 39;)' 那么此时的配置必须使用PASS()包进行解密,如下所示:

    Spring: datasource: #数据源基本配置 用户名:PASS(l 8 I 2 rqyppttnl 4x 8 vhrvaksudlstgzend/3 tonvtypwe 0 znwsw 0/5 jdus w9 ulm) 密码:PASS(ejycsbbl 8 PMF 2 hubih 7 dhhpfdzclyjcegmr 9 Java 3 apjtvftx 9 tvdhupsaxjq 2 pnj) driver-class-name:com . MySQLSummary jasypt有很多高级的。

    三、接口返回数据如何脱敏?

    通常,接口返回值中的一些敏感数据会被脱敏,比如身份证号、手机号、地址...通常的方法是用*隐藏一些数据,当然也可以根据自己的需求定制。

    反正怎么优雅的实现呢?有两种实现方案,如下:

  • 集成Mybatis插件,查询时脱敏特定字段。
  • 集成Jackson,在序列化阶段对特定字段进行脱敏。
  • 基于哈丁球实现数据脱敏,查看上一篇文章:基于哈丁球实现数据“一键脱敏”
  • 第一种方案在线实现的方式有很多种,下面演示第二种,集成杰克逊。

    1. 自定义一个Jackson注解

    您需要自定义一个脱敏注释。一旦标记了一个属性,就相应地降低它的敏感度,如下所示:

    大数据如何采集

    /** *自定义杰克逊评论,对属性 */ @ retention(保留策略。运行时) @ target (elementtype。field) @ jacksonannotationside @ JSON serialize(using = sensitvejonserializer . class) public @ interface sensitive { //脱敏策略 sensitive strategy strategy(); } 2。定制脱敏策略根据项目需求定制不同领域的脱敏规则,如将手机号中间数字替换为*,如下:

    /** *脱敏策略,枚举类,针对不同数据定制特定策略 */ 公共enum敏感策略{ /* * *用户名 */ 。s . replace all(& # 34;S(S *)& # 34;, "*")、 /** *身份证 */ ID _ card(s-->:s . replace all(& # 34;(d { 4 })d { 10 }(w { 4 })& # 34;, "****")、 /** *手机号码 */ phone(s->;s . replace all(& # 34;(d { 3 })d { 4 }(d { 4 })& # 34;, "****"), /** *地址 */ 地址(S-->:S . replace all(& # 34;S { 3 })S { 2 }(S *)S { 2 } & # 34;, "********")); 私有最终函数& ltString,String & gt脱敏剂; SensitiveStrategy(函数& ltString,String & gt脱敏剂){ this .脱敏剂=脱敏剂; } 公共函数& ltString,String & gt脱敏剂(){ 返回脱敏剂; } } 以上只是提供的一部分,根据自己的项目需求进行配置。

    3. 定制JSON序列化实现

    下面将是一个重要的实现,它对标注了annotation @Sensitive的字段进行脱敏,实现如下:

    /** *序列化批注的自定义实现 * JSON序列化程序< String & gt:指定字符串类型,并使用serialize()方法将修改后的数据加载到 */ 公共类敏感jsonserializer扩展JSON serializer < String & gt实现contextual serializer { private sensitive strategy策略; @ Override public void serialize(String value,JsonGenerator gen,SerializerProvider serializers)抛出io exception { gen . writestring(strategy . designiter()。应用(值)); } /** *获取批注属性 */ @ override public JSON serializer <?& gtcreate contextual(serializer provider prov,BeanProperty property)抛出JsonMappingException { Sensitive annotation = property . get annotation(Sensitive . class); if(objects . nonnull(annotation)& & objects . equals(string . class,property.getType()。getraw class())){ this . strategy = annotation . strategy(); 返回此; } return prov . findvalueserializer(property . gettype(),属性); } } 4。定义Person类并对其数据进行脱敏使用annotation @Sensitive annotation对数据进行脱敏,代码如下:

    @ data public class person { /* * *实名 */ @ Sensitive(strategy = Sensitive strategy . username) private string实名; /** *地址 */ @敏感(策略=敏感策略。address) 私有字符串地址; /** *电话号码 */ @ sensitive(strategy = sensitive strategy . phone) 私有字符串电话号码; /** *身份证号 */ @ sensitive(strategy = sensitive strategy . ID _ card) 私串身份证; } 5。模拟接口测试以上四个步骤完成了杰克逊对数据脱敏的注解。写一个控制器来测试一下,代码如下:

    @ rest controller 公共类test controller { @ get mapping(& # 34;/test & # 34;) 公众人物测试(){ 人物用户=新人(); user . set real name(& # 34;只有陈某& # 34;); user . set phone number(& # 34;19796328206"); user . set address(& # 34;浙江省杭州市温州市..."); user . setid card(& # 34;4333333333334334333"); 返回用户; } } 调用接口检查数据是否正常脱敏,结果如下:

    { & # 34;realName & # 34: "不*陈某& # 34;, & # 34;地址& # 34;: "浙江省温州市...* ****", & # 34;电话号码& # 34;: "197****8206", & # 34;idCard & # 34: "4333****34333" } 6。总结数据脱敏的实现方式有很多种,关键是哪种更适合,哪种更优雅。.....

    四、日志文件如何数据脱敏?

    配置文件和接口返回值的数据脱敏上面已经介绍过了,现在总是轮到日志脱敏了。在项目中,打印日志是不可避免的,肯定会涉及到一些敏感数据被明文打印出来,所以需要过滤掉这些敏感数据(身份证、号码、用户名等...).

    log4j2为例,说明如何对日志进行脱敏。其他的日志框架也有同样的思路。

    1. 添加log4j2日志依赖

    Spring Boot的默认日志框架是logback,但是我们可以切换到log4j2,具体取决于以下几点:

    & lt依赖性& gt & lt;groupId & gtorg . spring framework . boot & lt;/groupId & gt; & lt;artifactId & gtspring-boot-starter-web & lt;/artifact id & gt; & lt;!-删除springboot的默认配置-& gt; & lt;排除事项& gt & lt;排除& gt & lt;groupId & gtorg . spring framework . boot & lt;/groupId & gt; & lt;artifactId & gt弹簧启动启动记录& lt/artifact id & gt; & lt;/exclusion & gt; & lt;/exclusions>。 & lt;/dependency & gt; & lt;!-用log4j2替换logback-->: & lt;依赖性& gt & lt;groupId & gtorg . spring framework . boot & lt;/groupId & gt; & lt;artifactId & gtspring-boot-starter-log4j 2 & lt;/artifact id & gt; & lt;/dependency & gt; 2。在/resource目录中创建新的log4J2。XML配置log4j 2的日志配置非常简单。只需在/resource文件夹中创建一个新的log4j2.xml配置文件,如下所示:





    上面的配置没有实现数据脱敏。这是一个常见的配置,使用PatternLayout

    3. 自定义PatternLayout实现数据脱敏

    步骤2中的配置使用PatternLayout的格式来实现日志,所以我们也可以自定义一个PatternLayout来实现日志过滤和脱敏。

    PatternLayout的类图继承关系如下:




    从上图可以清楚的看到,PatternLayout继承了一个抽象类AbstractStringLayout,所以你只需要继承这个抽象类就可以自定义了。

    1。创建CustomPatternLayout并继承抽象类abstractstringlayout

    代码如下:

    /** * log4j2脱敏插件 *继承abstractring layout * */ @ plugin(name = & # 34;CustomPatternLayout & # 34,类别=节点。类别,元素类型=布局。ELEMENT_TYPE,print object = true) 公共类CustomPatternLayout扩展AbstractStringLayout { 公共最终静态记录器Logger = Logger factory . get Logger(CustomPatternLayout . class); 私有模式布局模式布局; protected CustomPatternLayout(Charset Charset,String pattern){ super(Charset); pattern layout = pattern layout . new builder()。withPattern(模式)。build(); init rule(); } /** *要匹配的正则表达式映射 */ 私有静态映射

    2。定制你自己的脱敏规则

    上面代码中的Log4j2Rule是一个脱敏规则的静态类。我把它直接放在静态类中进行配置,在实际项目中可以设置为配置文件。代码如下:

    /** *被阻止的加密日志有三种类型: * 1,ID * 2,name * 3,ID *加密的规则可以在配置文件中优化 * */[ String,String & gtregularMap = new HashMap & lt& gt(); /** * TODO可配置 *此项可以放在后面的配置项中 */ public static final string user _ name _ str = & # 34;姓名、姓名、联系人、姓名& # 34;; public static final String USER _ id card _ STR = & # 34;EmpCard,idCard,身份证,身份证号& # 34;; public static final String USER _ PHONE _ STR = & # 34;手机,手机,手机,手机,手机& # 34;; /** *常规匹配,并且可以自定义 */ 私有静态字符串ID card _ regexp = & # 34(d { 17 }[0-9Xx]| d { 14 }[0-9Xx])& # 34;; 私有静态字符串USERNAME _ REGEXP = & # 34[u4e00-u9fa5]{2,4 } & # 34;; 私有静态字符串PHONE _ REGEXP = & # 34(?& lt!d)(?:(?:1[3456789]d{9})|(?:861[356789]d{9})(?!d)& # 34;; static { regular map . put(USER _ NAME _ STR,USERNAME _ REGEXP); regular map . put(USER _ id card _ STR,id card _ REGEXP); regular map . put(USER _ PHONE _ STR,PHONE _ REGEXP); } } 经过以上两步,自定义PatternLayout已经完成,接下来将重写配置文件log4j2.xml。

    4. 修改log4j2.xml配置文件

    其实这里的修改很简单。原始的配置文件是使用PatternLayout直接格式化的,所以只有缺省的



    全球替换就行了。至此,这个配置文件已经被修改。

    5. 演示效果

    第三步中,定制脱敏规则的静态类Log4j2Rule,其中姓名、身份证、号码三个脱敏规则定义如下:



    我们来论证一下这三个规则是否可以正确脱敏,直接使用日志打印。代码如下:

    @ Test public void test3(){ log . debug(& # 34;身份证:{},姓名:{},电话:{ } & # 34;,"320829112334566767","只有陈某& # 34;,"19896327106"); } 控制台打印的日志如下:

    身份证:320829 * * * * * 566767,姓名:无* * *,电话:198 * * * * 106 哦,成功了,好容易!!!

    6. 总结

    日志脱敏的方案有很多,陈某只是介绍了一个常见的,有兴趣可以研究一下。

    您可以还会对下面的文章感兴趣

    使用微信扫描二维码后

    点击右上角发送给好友