数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。 —— [ 百度百科 ]
本文使用最简单的脱敏方式进行数据脱敏打印,规则如下:
| 参数 | 脱敏前 | 脱敏后 |
| ——– | ——– | ——– |
| 姓名 | 李丽丽 | 李** |
| 手机号 | 13898701234 | 138****1234 |
| 身份证号 | 111111111111115762 | **************5762 |
| 银行卡号 | 6222600890987671234 | 6222600********1234 |
如果你的项目中这些需要脱敏的字段定义是统一的标准,如:**Name、cardId、mobile等命名规范的请参考博文:
https://blog.csdn.net/fywfengyanwei/article/details/78484590 博主写的很不错。但是如果你的项目中字段没有按照统一的标准定义字段名称又需要做脱敏处理的请参考本文,废话不多说上代码:
创建一个类继承 MessageConverter实现其convert方法,是因为这个是logback日志打印记录的入口,获取日志内容进行相应处理:
import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.utils.MobileHandlerUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author LGH
* @description 日志打印进行相应脱敏处理
* @date 2019/4/25 11:06
*/
@Slf4j
public class SensitiveDataConverter extends MessageConverter {
private static final String MOBILE_REGEX = "((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}";
@Override
public String convert(ILoggingEvent event){
// 获取原始日志
String requestLogMsg = event.getFormattedMessage();
// 获取返回脱敏后的日志
return convertMsg(requestLogMsg);
}
/**
* 处理日志字符串,返回脱敏后的字符串
* @param oriMsg
* @return
*/
public String convertMsg(final String oriMsg){
String tempMsg = oriMsg;
if (tempMsg != null && !"".equals(tempMsg)){
tempMsg = mobileHandler(tempMsg);
}
return tempMsg;
}
/**
* 查询符合规则的字符串手机号码
* 注意:如果手机号有新增号码段需要修改正则表达式
* @param msg
*/
private String mobileHandler(String msg){
// 将给定的正则表达式编译到模式中
Pattern pattern = Pattern.compile(MOBILE_REGEX);
// 创建匹配给定输入与此模式的匹配器。
Matcher matcher = pattern.matcher(msg);
// 脱敏处理:查找字符串中是否有符合的子字符串
StringBuffer sb = new StringBuffer() ;
while(matcher.find()){
// 查找到符合规则的手机号
String tmp = matcher.group() ;
// 两个判断条件针对两种参数:1、json字符串格式请求;2、json转为VO之后的日志打印
if (getChar(msg,msg.indexOf(tmp)-1) == '"' && getChar(msg,msg.indexOf(tmp)+11) == '"'){
// 处理手机号
String v = MobileHandlerUtil.mobileHandler(tmp);
// 替换掉查找到的字符串
matcher.appendReplacement(sb, v) ;
}else if (getChar(msg,msg.indexOf(tmp)-1) == '=' && getChar(msg,msg.indexOf(tmp)+11) == ','){
// 处理手机号
String v = MobileHandlerUtil.mobileHandler(tmp);
// 替换掉查找到的字符串
matcher.appendReplacement(sb, v);
}
}
matcher.appendTail(sb) ;
return sb.toString();
}
/**
* 获取指定位置的字符
* @param msg
* @param index
* @return
*/
private char getChar(String msg, int index){
return msg.charAt(index);
}
}
工具类:
import org.apache.commons.lang.StringUtils;
/**
* @author LGH
* @description 日志打印过程中针对客户的手机号敏感信息处理工具
* @date 2019/4/24 18:22
*/
public class MobileHandlerUtil {
private MobileHandlerUtil() {
throw new IllegalStateException("此类不能实例化!!!");
}
/**
* 手机号码保留前三位和后四位,其他隐藏<如:188******1234>
* @param mobile 手机号
* @return String
*/
public static String mobileHandler(String mobile){
if (!StringUtils.isBlank(mobile)) {
mobile =mobile.substring(0, 3) + "****" + mobile.substring(7, mobile.length());
}
return mobile;
}
}
logback日志配置文件配置:
<configuration>
<conversionRule conversionWord="msg" converterClass="com.config.SensitiveDataConverter"></conversionRule>
</configuration>
详细配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Logback默认配置的采用的步骤 -->
<!-- 1. 尝试在 classpath 下查找文件 logback-test.xml; -->
<!-- 2. 如果文件不存在,则查找文件 logback.xml; -->
<!-- 3. 如果两个文件都不存在,logback 用 BasicConfigurator 自动对自己进行配置,这会导致记录输出到控制台。 -->
<!-- 本机环境中只会加载该配置文件,部署服务器时请删除本文件 -->
<conversionRule conversionWord="msg" converterClass="com.config.SensitiveDataConverter"> </conversionRule>
<!-- 输出控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<encoder>
<Pattern><![CDATA[ [%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t] [%logger.%method:%line] -- %msg%n ]]></Pattern>
</encoder>
</appender>
<!-- 时间滚动输出日志 -->
<appender name="file—info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>D:/logs/aaaa.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>D:/logs/aaaa.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern><![CDATA[ [%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t] [%logger.%method:%line] -- %msg%n ]]></pattern>
</encoder>
</appender>
<logger name="dfpay-auto" additivity="false">
<appender-ref ref="INFO_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="console" />
</root>
</configuration>
如此启动之后就会把所有日志中出现的手机进行中间四位*处理。
下面附上身份证、银行卡的正则方便后续使用和扩展:
身份证:
十八位: ^[1-9]\d{5}(18|19|([23]\d))\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{2}$
如有披露或问题欢迎留言或者入群探讨