首页 > 其他分享 >[日志] 日志脱敏实践

[日志] 日志脱敏实践

时间:2023-07-20 18:56:05浏览次数:36  
标签:return String 实践 log4j org import 日志 public 脱敏

1 序言

思路:根据待输出的关键字段名称进行不可逆算法的(离线式)脱敏。

2 步骤

2.1 修改本工程的日志框架为 Log4j2

slf4j.version = 1.7.25
log4j.version = 2.13.3

<!-- log [start] -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>${slf4j.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>${log4j.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>${log4j.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j-impl</artifactId>
	<version>${log4j.version}</version>
</dependency>
<!-- log [end] -->

2.2 基于Log4j2自定义 StringLayout

Log4j2Rule

import com.google.common.collect.Lists;
import java.util.List;

public class Log4j2Rule {
    public static List<String> regulars = Lists.newArrayList();
    public static final String KEY_REGEXP = "@#.*?#@";

    public Log4j2Rule() {
    }

    static {
        regulars.add("@#.*?#@");
    }
}

CustomPatternLayout

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.johnnyzen.Log4j2Rule;
import java.nio.charset.Charset;
import java.util.Iterator;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Plugin(
    name = "CustomPatternLayout",
    category = "Core",
    elementType = "layout",
    printObject = true
)
public class CustomPatternLayout extends AbstractStringLayout {
    public static final Logger logger = LoggerFactory.getLogger(CustomPatternLayout.class);
    private PatternLayout patternLayout;

    protected CustomPatternLayout(Charset charset, String pattern) {
        super(charset);
        this.patternLayout = PatternLayout.newBuilder().withPattern(pattern).build();
    }

    public String hideMarkLog(String logStr) {
        try {
            if (!StringUtils.isBlank(logStr) && !CollUtil.isEmpty(Log4j2Rule.regulars)) {
                Iterator var2 = Log4j2Rule.regulars.iterator();

                while(var2.hasNext()) {
                    String regular = (String)var2.next();
                    if (ReUtil.count(regular, logStr) > 0) {
                        logStr = matchingAndEncrypt(logStr, regular);
                    }
                }

                return logStr;
            } else {
                return logStr;
            }
        } catch (Exception var4) {
            logger.info(">>>>>>>>> 脱敏处理异常 ERROR:{}", var4);
            return logStr;
        }
    }

    private static String matchingAndEncrypt(String msg, String regExp) {
        return ReUtil.replaceAll(msg, regExp, (matcher) -> {
            String group = matcher.group();
            if (org.apache.commons.lang.StringUtils.isNotEmpty(group)) {
                group = StrUtil.sub(group, 2, -2);
                return SecureUtil.sha256(group);
            } else {
                return msg;
            }
        });
    }

    @PluginFactory
    public static Layout createLayout(@PluginAttribute("pattern") String pattern, @PluginAttribute("charset") Charset charset) {
        return new CustomPatternLayout(charset, pattern);
    }

    public String toSerializable(LogEvent event) {
        return this.hideMarkLog(this.patternLayout.toSerializable(event));
    }
}

2.3 修改日志的配置策略 (log4j.properties)

appender.{accessRollingFile/...}.layout.type=CustomPatternLayout

2.4 定义对象脱敏dValueFilter : TargetClassDesensitizationValueFilter


import com.alibaba.fastjson2.filter.ValueFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

public class TargetClassDesensitizationValueFilter implements ValueFilter {
    private final static Logger logger = LoggerFactory.getLogger(VehicleDesensitizationValueFilter.class);

    /**
     * 脱敏规则
     */
    public final static String DESENSITIZATION_REGEXP = "@#.*?#@";

    /** 用于 String.format(DESENSITIZATION_TEMPLATE, targetField) 的脱敏格式模板 **/
    public final static String DESENSITIZATION_TEMPLATE = "@#%s#@";

    public static String TARGET_FIELD_PARAM = "idCard";

    public static String TARGET_FIELD_LIST_PARAM = "idCardList";

    /**
     * 对象脱敏 | 基于 业务中台的 Layout : @#%s#@
     * @param object
     * @param propertyName
     * @param propertyValue
     * @return
     */
    @Override
    public Object apply(Object object, String propertyName, Object propertyValue) {
        logger.debug("object: {}, propertyName:{}, propertyValue: {}", object, propertyName, propertyValue);
        Object newPropertyValue = null; // 只要字段名中包含 TARGET_FIELD_PARAM ,则:值输出为 returnValue;
        if (propertyName.equals(TARGET_FIELD_PARAM)) {
            if(propertyValue instanceof String){
                String targetFieldValue = (String) propertyValue;
                return String.format(DESENSITIZATION_TEMPLATE, targetFieldValue);//  返回修改后的属性值
            } else {
                //Do Nothing
            }
        } else if(propertyName.equals(TARGET_FIELD_LIST_PARAM)) {
            if( (!ObjectUtils.isEmpty(propertyValue)) && (propertyValue instanceof List) ){
                List list = (List) propertyValue;
                Object firstElement = list.get(0);
                if(firstElement instanceof String){// list's data structure is List<String>
                    List<String> newTargetFieldValueList = new ArrayList<>();
                    targetFieldValueList.stream().forEach( targetFieldValue -> {
                        newTargetFieldValueList.add(String.format(DESENSITIZATION_TEMPLATE, targetFieldValue));
                    });
                    newPropertyValue = newTargetFieldValueList;
                    return newPropertyValue;
                }  else {
                   //Do Nothing
                }
            } else {
                //Do Nothing
            }
        }
        return propertyValue;
    }

    /**
     * 文本脱敏 (脱敏策略应用于文本) | 基于 base64
     * @return
     */
    public static String textDesensitization(String content){
        if(ObjectUtils.isEmpty(content)){
            return null;
        } else {
            if(content.contains(TARGET_FIELD_PARAM) || content.contains(TARGET_FIELD_LIST_PARAM)){
                return "#DESENSITIZATION_START#" + Base64Utils.encodeToString(content.getBytes()) + "#DESENSITIZATION_END#";
            }
        }
        return content;
    }
}

2.5 修改明文格式输出日志的代码为脱敏输出格式

	将含 targetFiled 的日志明文 转密文
		sample:  “3343243536” => "@#3343243536#@"
		
		场景1: 打印基本数据类型、字符串
			logger.info("targetFiled: {}", String.format("@#%s#@", "3343243536"));
	
		场景2: 打印对象
		    {"vin": "436345345"}
			logger.info("targetObject: {}", JSON.toJSONString(pageRequest, new TargetClassDesensitizationValueFilter()) );

2.6 打印效果

public class LogDesensitizationTest {
    private final static Logger logger = LoggerFactory.getLogger(LogDesensitizationTest.class);

    @Test
    public void test(){
        Map<String, Object> params = new HashMap<>();
        params.put("idCard", "35355");//{"idCard":"c69c21ce30afa92d6df9606c906fc1a4982922ae64982e20018ada97a3b1174a"}

        logger.info("idCard: {}", com.alibaba.fastjson2.JSON.toJSONString(params, new TargetClassDesensitizationValueFilter()));//
        logger.info("idCard: {}", TargetClassDesensitizationValueFilter.textDesensitization(String.format("idCard:43534534")));//#DESENSITIZATION_START#aWRDYXJkOjQzNTM0NTM0#DESENSITIZATION_END#
    }
}

标签:return,String,实践,log4j,org,import,日志,public,脱敏
From: https://www.cnblogs.com/johnnyzen/p/17569379.html

相关文章

  • 【网易云信】直播场景播放侧常见问题分析与实践经验
    常见的播放流程播放器主要流程分析 播放器的播放流程与推流过程类似,但是顺序相反。推流端先采集音频和视频,进行音视频编码和封装,并按照流媒体协议进行处理,最终得到输出流。而播放器则将输入流经过解析和解封装,得到音频包(如AAC)和视频包(如H.264、H.265),并进行解码以获取音频帧......
  • 搬运 -阮一峰的网络日志 --Flex 布局教程:实例篇
    原文链接:http://www.ruanyifeng.com/blog/2015/07/flex-examples.html语法: https://www.cnblogs.com/yuwen1995/p/17568483.html一、骰子的布局骰子的一面,最多可以放置9个点。下面,就来看看Flex如何实现,从1个点到9个点的布局。你可以到codepen查看Demo。如果不加说明,本节的......
  • 云原生基础设施实践:NebulaGraph 的 KubeBlocks 集成故事
    像是NebulaGraph这类基础设施上云,通用的方法一般是将线下物理机替换成云端的虚拟资源,依托各大云服务厂商实现“服务上云”。但还有一种选择,就是依托云数据基础设施,将数据库产品变成为云生态的一环,不只是提供自身的数据云服务,还能同其他的数据库一起分析挖掘业务数据价值。在本......
  • 人无完人,止于至善;躬身实践,方得始终
    人无完人,止于至善;躬身实践,方得始终   最近和女朋友发生了一些不快,两个人实际上都很疲惫,都渴望得到对方的关慰,可是身体却上不上劲,于是两败俱伤。其实两个人都没什么问题,都缺乏足够的休息与能量补充,睡一觉就好了的事儿,俩傻瓜都渴望得到对方帮助,还想通过吵架得到重视...... ......
  • CI流水线中Jenkins应用实践丨IDCF
    作者:达日汗,中国农业银行研发中心,系统支持部 CI(ContinuousIntegration)在维基百科中的定义是:经常将几个小改动合并到一个主分支中,强调开发人员提交了新代码之后,立刻进行构建和(单元)测试。持续集成可以帮助开发人员尽早定位到错误,控制开发流程,减少大量不必要的工作,提高工作效率。一......
  • 订单逆向履约系统的建模与 PaaS 化落地实践
    导读本文重点介绍了京东零售电商业务在订单逆向履约上面的最佳技术实践,京东零售快退平台承接了零售几乎所有售前逆向拦截和退款业务,并在长期的业务和技术探索中沉淀了丰富的业务场景设计方案、架构设计经验,既能承接面向消费者C端用户的高并发流量,同时也能满足集团复杂业务的订单......
  • Swagger和日志
    Swagger官网:https://swagger.io/Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务。功能主要包含以下几点:A.使得前后端分离开发更加方便,有利于团队协作B.接口文档在线自动生成,降低后端开发人员编写接口文档的负担C.接口功能测试......
  • oracle用户密码过期导致归档日志文件无法删除
    问题描述:oracle用户密码过期导致归档日志文件无法删除.系统:rhel7.3场景描述:生产环境系统u01目录使用率超告警阀值,经确认为归档占用大量空间,系统中有自动清理归档日志文件的脚本,为什么没有清理呢?1、异常分析--查/var/log/cron日志文件异常告警信息:Jul1001:00:01hisdb01CR......
  • 六月学习之Haproxy ACL实践(基于后缀调度)
    2、ACL场景实践2.4、ACL案例-基于后缀调度根据用户请求的后缀,调度到不同的后端集群用户通过.txt调度到172.16.1.7:80用户通过.pdf调度到172.16.1.8:802.4.1、配置后端节点#web1:.txt站点定义cat/etc/nginx/conf.d/www.qingchen.com.confserver{listen8080;server_......
  • JVM系统优化实践(20):GC生产环境案例(三)
    您好,这里是「码农镖局」51CTO博客,欢迎您来,欢迎您再来~某新手开发工程师接到了一个保存Elasticsearch日志的任务,以供后续分析之用。但写代码的时候,误将保存日志的代码段弄成了无限循环,程序启动后,没用多久就崩溃了。另一名工程师在动态创建类时,没有实现动态代理机制,也就没有缓存动态生......