java日志脱敏(密码/身份证/其他自定义等) logback
原文链接:https://blog.csdn.net/weixin_39286166/article/details/126889660
一.脱敏规则类 import ch.qos.logback.classic.pattern.MessageConverter; import ch.qos.logback.classic.spi.ILoggingEvent; import org.apache.commons.lang3.StringUtils; import org.springframework.util.CollectionUtils;import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/**
- 自定义日志脱敏类
- @Author: zengt
- @Date: 2022/9/8 17:22
*/
public final class SensitiveLogDataConverter extends MessageConverter {
//银行卡正则匹配 private final static Pattern BANK_CARD_PATTERN = Pattern.compile("(\\D)([3-6]\\d{3})(\\d{8,12})(\\d{4})(\\D)", Pattern.CASE_INSENSITIVE); //手机号正则匹配 private final static Pattern PHONE_PATTERN = Pattern.compile("(?<!\\d)(1\\d{10})(?!\\d)", Pattern.CASE_INSENSITIVE); //身份证正则匹配 private final static Pattern ID_CARD_PATTERN = Pattern.compile("([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}[\\dXx])|([1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3})", Pattern.CASE_INSENSITIVE); //姓名正则匹配 //姓名、realName 暂时不加密 -- luzy private final static Pattern NAME_PATTERN = Pattern.compile("(userName|receiveName)(=|=\\[|\\\":\\\"|:|:|=')([\\u4e00-\\u9fa5]{1})([\\u4e00-\\u9fa5]{1,3})(\\]|\\\"|'|)", Pattern.CASE_INSENSITIVE); //邮箱 private final static Pattern EMAIL_PATTERN = Pattern.compile("(\\w{1})(\\w*)(\\w{1})@(\\w+)(.com)", Pattern.CASE_INSENSITIVE); //其他(密码/地址/卡号等) //token暂时不加密 -- luzy private final static Pattern OTHER_PATTERN = Pattern.compile("(appId|authCode|password|密码|验证码|地址|住址|address|cardNo|卡号|card|cardNumber|app_key|appkey|appSecret|app_secret)(=|=\\[|\\\":\\\"|:|:|=')(.*?)(?>(\\]|[^\\\\\"]\\\"|'))", Pattern.CASE_INSENSITIVE); @Override public String convert(ILoggingEvent event) { try { final Set<String> list; String logMsg = event.getFormattedMessage(); list = validDate(logMsg); if (!CollectionUtils.isEmpty(list)) { for (String param : list) { String convertMsg = logMsg; logMsg = convertDate(convertMsg, param); } } return logMsg; } catch (Exception e) { e.printStackTrace(); } return super.convert(event); } /** * 正则匹配是否包含脱敏数据 */ private static Set<String> validDate(String param) { Set<String> set = new HashSet<>(); // 匹配手机号 Matcher phoneMatcher = PHONE_PATTERN.matcher(param); while (phoneMatcher.find()) { set.add(phoneMatcher.group()); } // 匹配身份证 Matcher idCardMatcher = ID_CARD_PATTERN.matcher(param); while (idCardMatcher.find()) { set.add(idCardMatcher.group()); } Matcher bankCardMatcher = BANK_CARD_PATTERN.matcher(param); while (bankCardMatcher.find()) { set.add(bankCardMatcher.group()); } Matcher namePatternMatcher = NAME_PATTERN.matcher(param); while (namePatternMatcher.find()) { set.add(namePatternMatcher.group()); } Matcher emailPatternMatcher = EMAIL_PATTERN.matcher(param); while (emailPatternMatcher.find()) { set.add(emailPatternMatcher.group()); } Matcher otherPatternMatcher = OTHER_PATTERN.matcher(param); while (otherPatternMatcher.find()) { set.add(otherPatternMatcher.group()); } return set; }
/** * 数据脱敏 */ private static String convertDate(String logMsg, String param) { if (PHONE_PATTERN.matcher(param).find()) { return logMsg.replace(param, param.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")); } else if (ID_CARD_PATTERN.matcher(param).find()) { String replaceContext = param.replaceAll(param, StringUtils.left(param, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(param, 4), StringUtils.length(param), "*"), "******"))); return logMsg.replace(param, replaceContext); } else if (BANK_CARD_PATTERN.matcher(param).find()) { String replaceContext = BANK_CARD_PATTERN.matcher(param).replaceAll("$1$2********$4$5"); return logMsg.replace(param, replaceContext); } else if (NAME_PATTERN.matcher(param).find()) { String replaceContext = NAME_PATTERN.matcher(param).replaceAll("$1$2$3**$5"); return logMsg.replace(param, replaceContext); } else if (EMAIL_PATTERN.matcher(param).find()) { String replaceContext = EMAIL_PATTERN.matcher(param).replaceAll("$1****$3@$4.com"); return logMsg.replace(param, replaceContext); } else if (OTHER_PATTERN.matcher(param).find()) { String replaceMent = "$1$2********$4"; String replaceContext = OTHER_PATTERN.matcher(param).replaceAll(replaceMent); return logMsg.replace(param, replaceContext); } return logMsg; } }
二.logback指定脱敏覆盖类
<!-- 指定脱敏类的位置 --> <conversionRule conversionWord="msg" converterClass="cn.***.SensitiveLogDataConverter"/>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2021-08-01 $(document).ready和window.onload区别
2021-08-01 为什么script标签一般放在body下面
2021-08-01 idea添加jar和移除jar包的三种方式
2021-08-01 HTML转义字符大全(转)
2021-08-01 C#中 以固定长度 取字符串中的数据
2021-08-01 Oracle的substr函数简单用法和 C#中一样
2021-08-01 ORA-22835:缓冲区对于CLOB到CHAR转换而言太小