logback日志脱敏处理

logback.xml配置文件修改

<springProperty scope="context" name="log.consolePattern" source="hcf.log.console-pattern" defaultValue="%red(%d{yyyy-MM-dd HH:mm:ss.SSS})|%highlight(%level)|%green(%thread)|%X{clientIp}|%X{traceId}|%X{rpcId}|%boldMagenta(%c.%M[%L])|%cyan(%msg%n)"/>
<conversionRule conversionWord="msg" converterClass="com.credithc.channel.common.util.SensitiveConverter"> </conversionRule>

特别注意:

1、conversionRule标签必须紧挨着configuration标签写,绝对不可以放在appender标签下面,但是可以放在springProperty下面
2、conversionRule标签中的converterClass属性指向的是我们自定义的处理敏感信息的类,conversionWord的值对应的是我们定义的日志格式中的日志内容的占位符,也就是上面代码中%msg去掉%的部分


脱敏处理类

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;

public class SensitiveConverter extends MessageConverter {
    //手机号正则匹配
    private static final String PHONE_REGEX = "1[3|4|5|7|8][0-9]\\d{8}";
   //身份证号正则匹配   private static final String IDCARD_REGEX = "([1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx])|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3})";
      //之所以定义这个参数,完全是处于公司的要求,因为公司要求敏感信息在日志输出时被脱敏后,还能按照一定的规则还原,所以就用这些字母来进行处理了,对于没有这种要求的,就更简单了,直接用*去脱敏就可以了,大家很容易根据现在的代码进行改造,这里不在多讲  private static final String KEY = "axedfqLGpu";
    @Override
    public String convert(ILoggingEvent event){

        // 获取原始日志
        String requestLogMsg = event.getFormattedMessage();

        // 获取返回脱敏后的日志
        return filterSensitive(requestLogMsg);
    }
    
    /**
     * 对敏感信息脱敏
     * @param content
     * @return
     * @author mlf
     * @date 2020年06月18日
     */
    public static String filterSensitive(String content) {
        try {
            if(StringUtils.isBlank(content)) {
                return content;
            }
            content = filterIdcard(content);
            return filterMobile(content);
        }catch(Exception e) {
            return content;
        }
    }
    
    /**
     * [身份证号] 指定展示几位,其他隐藏 。<例子:1101**********5762>
     * @param num
     * @return
      * @author mlf
     * @date 2020年06月18日
     */
    private static String filterIdcard(String num){
        Pattern pattern = Pattern.compile(IDCARD_REGEX);
        Matcher matcher = pattern.matcher(num);
        StringBuffer sb = new StringBuffer() ;
        while(matcher.find()){
            matcher.appendReplacement(sb, baseSensitive(matcher.group(), 4, 4));
        }
        matcher.appendTail(sb) ;
        return sb.toString();
    }
    
    /**
     * [手机号码] 前三位,后四位,其他隐藏<例子:138******1234>
     * @param num
     * @return
    * @author mlf
     * @date 2020年06月18日
     */
    private static String filterMobile(String num){
        Pattern pattern = Pattern.compile(PHONE_REGEX);
        Matcher matcher = pattern.matcher(num);
        StringBuffer sb = new StringBuffer() ;
        while(matcher.find()){
            matcher.appendReplacement(sb, baseSensitive(matcher.group(), 3, 4)) ;
        }
        matcher.appendTail(sb) ;
        return sb.toString();
    }
    
    /**
     * 基础脱敏处理 指定起止展示长度 剩余用"KEY"中字符替换
     *
     * @param str         待脱敏的字符串
     * @param startLength 开始展示长度
     * @param endLength   末尾展示长度
     * @return 脱敏后的字符串
     */
    private static String baseSensitive(String str, int startLength, int endLength) {
        if (StringUtils.isBlank(str)) {
            return "";
        }
        String replacement = str.substring(startLength,str.length()-endLength);
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<replacement.length();i++) {
            char ch;
            if(replacement.charAt(i)>='0' && replacement.charAt(i)<='9') {
                ch = KEY.charAt((int)(replacement.charAt(i) - '0'));
            }else {
                ch = replacement.charAt(i);
            }
            sb.append(ch);
        }
        return StringUtils.left(str, startLength).concat(StringUtils.leftPad(StringUtils.right(str, endLength), str.length() - startLength, sb.toString()));
    }
    
    /**
     * 按"KEY"中字符解密
     * @param str
     * @param startLength
     * @param endLength
     * @return
   * @author mlf
     * @date 2020年06月18日
     */
    private static String decrypt(String str, int startLength, int endLength) {
         if (StringUtils.isBlank(str)) {
             return "";
         }
         String replacement = str.substring(startLength,str.length()-endLength);
         StringBuffer sb = new StringBuffer();
         for(int i=0;i<replacement.length();i++) {
             int index = KEY.indexOf(replacement.charAt(i));
             if(index != -1) {
                 sb.append(index);
             }else {
                 sb.append(replacement.charAt(i));
             }
         }
         return StringUtils.left(str, startLength).concat(StringUtils.leftPad(StringUtils.right(str, endLength), str.length() - startLength, sb.toString()));
    }
}

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值