java日志脱敏(密码/身份证/其他自定义等)

2023-11-02

一.脱敏规则类
 
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"/>

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java日志脱敏(密码/身份证/其他自定义等) 的相关文章

  • @Nullable 和 SonarQube “有条件执行的块应该可达”警告

    包有以下package info java ParametersAreNonnullByDefault package foo import javax annotation ParametersAreNonnullByDefault 类有
  • 在 Java 中,三个 true 输入的 XOR 返回 true。为什么?

    下面的代码 System out println 1 0 0 true false false System out println 1 0 1 true false true System out println 1 1 0 true t
  • 如何为带有未确定的“?”的Java通用Map添加值值类型?

    我在 JDK 8 示例中看到过这种声明 Map
  • 可以使用注解进行代码注入吗?

    我意识到这可能是一个已经被提出和回答的问题 但请耐心等待 我想知道是否可以使用注释将代码注入到类编译时 典型的示例是为对象的成员生成 getter 和 setter 这并不完全是我所需要的 但它可以说明基本思想 现在在互联网上我得到的基本答
  • 正则表达式查找两个字符之间的内部匹配

    环境 Java 我想匹配两个字符串之间的字符 这是一个例子 foo
  • 如何设置Java线程的CPU核心亲和力?

    我搜索了以前关于类似主题的帖子 但找不到合适的答案 因此提出这个问题 非常感谢您帮助回答 我知道在 Linux 中通过任务集命令设置进程与特定 CPU 核心的关联性 但我想设置 Java 线程与特定 cpu 核心的亲和力 以便属于同一进程的
  • 从java应用程序发送电子邮件时出现异常:中继被拒绝

    我们正在使用 Spring Mail 从 java 应用程序发送电子邮件 org springframework mail javamail JavaMailSenderImpl Spring电子邮件配置是
  • 使用 Windows 锁定屏幕后删除 Kerberos 缓存票证

    无论如何 有没有办法阻止 Kerberos 缓存的票证在 Windows 进入锁定屏幕后被删除 首次登录 Windows 时 klist exe 显示 2 个缓存票证 但是 发生 Windows 锁屏事件后 klist exe 显示 0 个
  • 在 Retrofit 中的 POST 请求中发送空正文

    我的 api 需要一个空的 json 主体 发出帖子请求时 如何在 Retrofit 和 Jackson 中进行设置 我尝试通过null 和空字符串 以及 但无法让它发挥作用 POST my url Call
  • 从两个数组中查找公共文件

    我正在尝试从两个数组中查找通用名称文件 我已将两个不同文件夹的文件名保存在两个不同的数组中 现在我正在创建一个通用文件数组 其中包含具有通用名称的文件 filenames 1 包含文件夹 1 中文件名称的数组 filename2 包含文件夹
  • c3p0 Java 数据库池、故障转移配置

    当数据库关闭时 IP 和端口会自动切换到另一个数据库服务器 我应该如何配置 Web 应用程序的 c3p0 连接池以遵循此数据库故障转移机制 目前 我使用的是 c3p0 但是在上次数据库故障转移中 池连接无法重新建立 请求失败后重新建立 有助
  • 在 Tomcat 中触发内部 ServletRequest

    我正在使用 Quartz 来安排 Web 应用程序的后台任务 其中一些任务只是针对同一 Web 应用程序发出请求 我想避免依赖于任何类型的网络设置 例如 如果从数据中心内发出带有我自己域名的请求 则可能无法正确路由 是否有一个 Java A
  • 错误:找不到符号 ArrayList

    我正在尝试创建某种列表来存储数组 表 中的值 我在这里使用数组列表 但我应该使用列表吗 但是 每次我尝试编译时 它都会引发以下错误 找不到标志 符号 ArrayList类 位置 玩家类 TablePlayer 代码如下 public cla
  • Eclipse java 断点 - 目的是什么?

    我正在学习 Android 教程 刚刚进入调试部分 我想知道断点的用途是什么 我还不能告诉 它实际上停止了应用程序 以便我可以确定它运行到该点 或者我可以设置多个断点并将它们用作标记来从断点到断点检查 停止和运行 我的代码 断点是执行停止的
  • 在硬件级别模拟按键 - Windows

    我正在寻找一种语言或库 使我能够在最大可能的水平上模拟击键 而无需实际按下按键 我对击键级别的具体衡量标准是 当我的计算机已经运行按键侦听器 例如鼠标键和粘滞键 时 它是否会产生与物理按键相同的输出 我尝试过很多击键模拟的方法 java A
  • 用 Java 编写“漂亮”代码的标准? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Xuggler 未转换 .webm 文件?

    我只是尝试使用 Xuggler 将 mov 文件转换为 webm 这应该可以工作 因为 FFMPEG 支持 webm 文件 这是我的代码 IMediaReader reader ToolFactory makeReader home use
  • Apache Beam:如何在使用重复数据删除功能时解决“ParDo 需要确定性密钥编码器才能使用状态和计时器”

    我正在尝试使用 Apache Beam 的重复数据删除功能对来自 Google Cloud Pubsub 的输入消息进行重复数据删除 但是 我创建后遇到错误KV
  • 如何从项目文件夹中的 jlabel 上设置图像?

    我正在尝试制作一个 Java 桌面应用程序 我想设置一个图像JLabel 我正在使用 NetBeans 从我的项目文件夹中 我的目录结构是 F gt MARKET src lib src defaultpackage demo java i
  • 无法以联觉方式绘制像素、Pi 数

    我想将 pi 数字的每个数字打印为彩色像素 因此 我得到一个带有 pi 数字的输入 然后将其解析为一个列表 每个节点包含一个数字 我知道 稍后我将使用一个数组 但我从来没有把它画到屏幕上 有人能帮我看看我错在哪里吗 import java

随机推荐

  • Pycharm配置——解释器(interpreter)

    今天打开pycharm运行一段代码 结果遇到了这个问题 以上应该是没有配置解释器的问题 那我是怎么解决这个问题的呢 1 打开文件 File 2 打开设置 Setting 3 打开新project的默认设置 4点击project Interp
  • vue3使用高德地图api,海量点,多边形围栏,热力图,轨迹线(二)

    五 MassMarks海量点标记 let mass 此处我定义了6种海量点图标 此处url我用的是项目中本地引入的图片 也可以填在线url链接 props infoList是项目后端返回的所有点的信息数组 其中每个点对象有个style字段
  • ArcGIS Pro 一打开Notebook笔记本工具软件就崩溃(停止运行)

    先说结论 如果对于ArcGIS Pro的笔记本工具 包括新建 添加 打开等一切操作 只要一点开 ArcGIS Pro就停止运行 一个可能的原因是Temp文件夹或者是其他文件的路径中有中文 可以尝试将路径修改为全英文 再次运行 其实这个问题是
  • 程序员的自我修养--链接、装载与库笔记:可执行文件的装载与进程

    可执行文件只有装载到内存以后才能被CPU执行 1 进程虚拟地址空间 程序和进程有什么区别 程序 或者狭义上讲可执行文件 是一个静态的概念 它就是一些预先编译好的指令和数据集合的一个文件 进程则是一个动态的概念 它是程序运行时的一个过程 很多
  • centos开放端口号的常用命令

    1 开放端口 firewall cmd zone public add port 5672 tcp permanent 开放5672端口 firewall cmd zone public remove port 5672 tcp perma
  • spring cloud项目升级spring boot 2.0爬过的坑

    注 升级后spring boot为2 0版本 spring cloud为Finchley M8版本 2 0官方文档地址 https docs spring io spring boot docs current reference html
  • 活动报名丨LLaMA一作:如何构建开源高效的基础语言模型(智源Live 38期)

    4月26日 星期三 下午16 00 17 30 智源LIVE 第38期 线上活动上 Meta AI研究科学家 LLaMA一作Hugo Touvron将分享 LLaMA Open and Efficient Foundation Langua
  • DOM4J对SOAP的返回信息解析

    用DOM4J的XML解析式拿不到节点的 所以网上利用DOM4J提供的VisitorSupport解决此问题 不废话 直接看代码 package com starhub util import org dom4j Document impor
  • 7个超好用的测试框架(总有一款适合你)

    昨天吃饭的时候和同事聊到测试框架 于是决定根据自己的实战工作经验总结一波好用的测试框架 本来文章里一共11个的 最后想想还是剔除掉了Maxim Cypress Gauge和ZTF Zentao Testing Framework 工具在精而
  • 【Python系列】eval 函数

    文章目录 1 基本概念 2 使用举例 3 eval 函数运用 计算器 4 不要滥用 eval 1 基本概念 eval 是 python 中功能非常强大的一个函数 将字符串当成有效的表达式来求值 并返回计算结果 所谓表达式就是 eval 这个
  • PyTorch深度学习实战(9)——学习率优化

    PyTorch深度学习实战 9 学习率优化 0 前言 1 学习率简介 2 梯度值 学习率和权重之间的相互作用 3 学习率优化实战 3 1 学习率对缩放后的数据集的影响 3 2 学习率对未缩放数据集的影响 小结 系列链接 0 前言 学习率 l
  • C++中的堆和栈

    堆栈其实是两种数据结构 堆栈都是一种数据项按序排列的数据结构 只能在一端 称为栈顶 top 对数据项进行插入和删除 要点 堆 顺序随意 栈 后进先出 Last In First Out 堆和栈的区别 一 预备知识 程序的内存分配 一个由C
  • 开源软件推介

    ag Grid 是一个企业级的 JavaScript 数据网格 ag Grid 的目的是提供可用于构建企业级应用的表格 例如报告和数据分析 业务流程和数据输入的数据表格 ag Grid 每一个功能的文档至少有一个例子来展示该功能 功能特性
  • 【工具类】double

    默认除法运算精度 private static final int DEF DIV SCALE 10 默认的保留位数 private static DecimalFormat df new DecimalFormat 0 00 提供精确的加
  • 怎么停止和重新启用hadoop的DataNode

    停止 比如我原来有10个节点的集群 现在我想停掉2个 但数据不能丢失 只能让它们的数据转移到其它8台上 这道过程就是decommission 我们不能直接把那2台停掉 要在停掉之前把数据转移出去 首先建立一个excludes文件 它是一个文
  • 如何在cmd环境中激活TensorFlow的环境

    一 如何安装TensorFlow环境 1 首先要安装好Anaconda 然后在cmd中检查cond的版本 2 要安装TensorFlow 在cmd终端输入 conda create name tensorflow python 3 5 2
  • 什么是 Dynamics 365

    什么是Dynamics 365 Dynamics 365是一组智能业务应用程序 通过预测性的 AI 驱动型见解 帮助您开展整体业务并实现更出色的成果 将潜在客户转化为忠实客户 培养更多销售就绪型潜在顾客 实现购买体验的个性化 大规模建立客户
  • onnx模型裁剪一部分

    https github com onnx onnx blob main docs PythonAPIOverview md import onnx input path path to the original model onnx ou
  • 交换机和路由器各自实现的原理

    1 什么是交换机 交换机也叫交换式集线器 它通过对信息进行重新生成 并经过内部处理后转发至指定端口 具备自动寻址能力和交换作用 由于交换机根据所传递信息包的目的地址 将每一信息包独立地从源端口送至目的端口 避免了和其他端口发生碰撞 广义的交
  • java日志脱敏(密码/身份证/其他自定义等)

    一 脱敏规则类 import ch qos logback classic pattern MessageConverter import ch qos logback classic spi ILoggingEvent import or