当前位置: 首页 > news >正文

工具类篇【四】日志脱敏

-


工具类篇大全


工具类篇【一】String字符串


工具类篇【二】BigDecimal计算


工具类篇【三】日期Date转换


工具类篇【四】日志脱敏


工具类篇【五】Random随机生成字符串


工具类篇【六】克隆对象的2种常用方法

 


前言
随着科技和信息化时代的加速发展,尤其在5G和大数据时代的今天,信息安全也逐渐成为人民更为关注的事情。为用户和会员保护个人隐私信息显得尤为重要。对于一些敏感数据的展示和存储,公司安全部门经常要求加密或脱敏处理。对敏感数据进行MD5加密存储,前端和日志脱敏处理。如:身份证、手机号、姓名、地址等,尤其是对敏感数据安全性要求较高行业和公司;电商、通信、金融等行业。


一、logback工具包
今天主要讲述后台系统对于敏感数据进行日志脱敏处理,拿来即用的工具实现类。利用logback工具包的日志脱敏处理,非常简单和方便。主要分为以下几个步骤:


定义脱敏日志关键字
- 获取关键字开始索引位置
- 获取关键字结束索引位置
- 进行关键字脱敏处理

日志脱敏处理主工具类:


`package **.util;

import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.google.common.collect.Lists;

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

/**
@Author: *
* @Date: 2020/9/17 10:18
* @param: 数据脱敏处理转换类【logback包】
* @return:
*/
public class SensitiveDataConverter extends MessageConverter {

/**
* 日志脱敏开关
*/
private static String converterCanRun = "true";
/**
* 日志脱敏关键字
*/
private static String sensitiveDataKeys = "idcard,realname,bankcard,mobile,shipAddress,detailedAddr,customerName,shipAddriess";

private static Pattern pattern = Pattern.compile("[0-9a-zA-Z]");

@Override
public String convert(ILoggingEvent event){
// 获取原始日志
String oriLogMsg = event.getFormattedMessage();

// 获取脱敏后的日志
String afterLogMsg = invokeMsg(oriLogMsg);
return afterLogMsg;
}
/**
* 处理日志字符串,返回脱敏后的字符串
* @param: msg
* @return
*/
public static String invokeMsg(final String oriMsg){
String tempMsg = oriMsg;
if("true".equals(converterCanRun)){
// 处理字符串
if(sensitiveDataKeys != null && sensitiveDataKeys.length() > 0){
String[] keysArray = sensitiveDataKeys.split(",");
for(String key: keysArray){
int index= -1;
do{
index = tempMsg.indexOf(key, index+1);
if(index != -1){
// 判断key是否为单词字符
if(isWordChar(tempMsg, key, index)){
continue;
}
// 寻找值的开始位置
int valueStart = getValueStartIndex(tempMsg, index + key.length());

// 查找值的结束位置(逗号,分号)........................
int valueEnd = getValuEndEIndex(tempMsg, valueStart);

// 对获取的值进行脱敏
String subStr = tempMsg.substring(valueStart, valueEnd);
subStr = tuomin(subStr, key);
///
tempMsg = tempMsg.substring(0,valueStart) + subStr + tempMsg.substring(valueEnd);
}
}while(index != -1);
}
}
}
return tempMsg;
}

/**
* 判断从字符串msg获取的key值是否为单词
* index为key在msg中的索引值
* @return
*/
private static boolean isWordChar(String msg, String key, int index){
// 必须确定key是一个单词............................
if(index != 0){ // 判断key前面一个字符
char preCh = msg.charAt(index-1);
Matcher match = pattern.matcher(preCh + "");
if(match.matches()){
return true;
}
}
// 判断key后面一个字符
char nextCh = msg.charAt(index + key.length());
Matcher match = pattern.matcher(nextCh + "");
if(match.matches()){
return true;
}
return false;
}

/**
* 获取value值的开始位置
* @param msg 要查找的字符串
* @param valueStart 查找的开始位置
* @return
*/
private static int getValueStartIndex(String msg, int valueStart ){
// 寻找值的开始位置.................................
do{
char ch = msg.charAt(valueStart);
if(ch == ':' || ch == '='){ // key与 value的分隔符
valueStart ++;
ch = msg.charAt(valueStart);
if(ch == '"'){
valueStart ++;
}
break; // 找到值的开始位置
}else{
valueStart ++;
}
}while(true);
return valueStart;
}

/**
* 获取value值的结束位置
* @return
*/
private static int getValuEndEIndex(String msg,int valueEnd){
do{
if(valueEnd == msg.length()){
break;
}
char ch = msg.charAt(valueEnd);

if(ch == '"'){ // 引号时,判断下一个值是结束,分号还是逗号决定是否为值的结束
if(valueEnd+1 == msg.length()){
break;
}
char nextCh = msg.charAt(valueEnd+1);
if(nextCh ==';' || nextCh == ','){
// 去掉前面的 \ 处理这种形式的数据
while(valueEnd>0 ){
char preCh = msg.charAt(valueEnd-1);
if(preCh != '\\'){
break;
}
valueEnd--;
}
break;
}else{
valueEnd ++;
}
}else if (ch ==';' || ch == ',' || ch == '}'){
break;
}else{
valueEnd ++;
}

}while(true);
return valueEnd;
}

/**
* 调用脱敏工具类进行字段日志处理
* @param submsg
* @param key
* @return
*/
private static String tuomin(String submsg, String key){
// idcard:身份证号, realname:姓名, bankcard:银行卡号, mobile:手机号,attribute10,shipAddress,detailedAddr:地址
if("idcard".equals(key)){
return SensitiveInfoUtils.idCardNum(submsg);
}
if(Lists.newArrayList("realname","customerName").equals(key)){
return SensitiveInfoUtils.chineseName(submsg);
}
if("bankcard".equals(key)){
return SensitiveInfoUtils.bankCard(submsg);
}
if("mobile".equals(key)){
return SensitiveInfoUtils.mobilePhone(submsg);
}
if(Lists.newArrayList("attribute10","shipAddress","detailedAddr","shipAddriess").contains(key)){
return SensitiveInfoUtils.address(submsg);
}
return "";
}

public static void main(String[] args) {
String tempMsg = "{sign=f88898b2677e62f1ad54b9e330c0a27e, idcard=130333198901192762, realname=%E5%BE%90%E5%BD%A6%E5%A8%9C, key=c5d34d4c3c71cc45c88f32b4f13da887, mobile=13210141605, bankcard=6226430106137525}";
String tempMsg1 = "{\"reason\":\"成功 \",\"result\":{\"jobid\":\"JH2131171027170837443588J6\",\"realname\":\"李哪娜\",\"bankcard\":\"6226430106137525\",\"idcard\":\"130333198901192762\",\"mobile\":\"13210141605\",\"res\":\"1\",\"message\":\"验证成功\"},\"error_code\":0}";
String shipAddress ="{shipAddress=宁夏回族自治区.银川市.金凤区.长城中路街道收货人:+卜广龙手机号码:+13992283627}";
String detailedAddr ="{\"attribute10\":\"浙江省.杭州市.桐庐县.桐君街道.收货人: 陈静手机号码: 15168393010所在地区: 浙江省杭州市桐庐县城南街道详细地址: 白云源路1618号银通汽车4楼\"}";
SensitiveDataConverter sc = new SensitiveDataConverter();
System.out.println(sc.invokeMsg(tempMsg));
System.out.println(sc.invokeMsg(tempMsg1));
System.out.println(sc.invokeMsg(shipAddress));
System.out.println(sc.invokeMsg(detailedAddr));
}
}
`
二、关键字处理工具类
针对需要脱敏的关键字进行逐个个性化处理,也可定义方法动态传入关键字进行脱敏处理:


`package com.vip.fcs.app.ar.util;

import org.apache.commons.lang3.StringUtils;

/**
@Author: *
* @Date: 2020/9/17 10:23
* @param: 数据脱敏处理工具类
* @return:
*/
public class SensitiveInfoUtils {

/**
[姓名] 只显示第一个汉字,其他隐藏为星号<例子:李*>
*
* @param fullName
* @return
*/
public static String chineseName(String fullName) {
if (StringUtils.isBlank(fullName)) {
return "";
}
String name = StringUtils.left(fullName, 1);
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
}

/**
[身份证号] 显示最后四位,其他隐藏。共计18位或者15位。<例子:**5762>
*
* @param idCardNum
* @return
*/
public static String idCardNum(String idCardNum) {
if (StringUtils.isBlank(idCardNum)) {
return "";
}
String num = StringUtils.right(idCardNum, 4);
return StringUtils.leftPad(num, StringUtils.length(idCardNum), "*");
}

/**
[手机号码] 前三位,后四位,其他隐藏<例子:138*1234>
*
* @param num
* @return
*/
public static String mobilePhone(String num) {
if (StringUtils.isBlank(num)) {
return "";
}
return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 4),StringUtils.length(num), ""), "**"));
}

/**
[银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600*1234>
*
* @param cardNum
* @return
*/
public static String bankCard(String cardNum) {
if (StringUtils.isBlank(cardNum)) {
return "";
}
return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), ""), "*"));
}

/**
[会员地址] 前六位,其他用星号隐藏每位1个星号<例子:广东省广州市**>
*
* @param:cardNum
* @return
*/
public static String address(String address) {
if (StringUtils.isBlank(address) || address.length() <9) {
return "";
}
String name = StringUtils.left(address, 9);
return StringUtils.rightPad(name, StringUtils.length(address), "*");
}

}
`

http://www.zskr.cn/news/1433745.html

相关文章:

  • SpringCloud--Config Server配置中心学习总结
  • 学术文献自动化管理革命:Zotero SciPDF插件深度解析
  • 聊聊我在第三方支付公司的经历
  • FeignClient注解及参数问题
  • FUXA管道动画制作:从静态流程图到动态工业监控的转变
  • 2026年宜昌市CPPM报名十大核心问题全流程答疑 - 众智商学院课程中心
  • 【Python系列课程】NumPy数组计算(下):向量化运算、广播机制与聚合函数
  • 别再死记硬背公式了!用Python+PyTorch图解马尔可夫随机场(MRF)在图像去噪中的应用
  • 2026西安曲江家政服务行业观察:唐僧到家等机构如何引领行业规范化发展 - 资讯快报
  • 2026年苏州区域专业防水补漏3家本土合规服务企业全方位分析与场景适配解读 专业防水公司排名推荐(2026年5月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 老显卡(GTX750/1050)也能玩转AI绘画?手把手教你升级驱动装CUDA11.4
  • 3分钟快速解密QQ音乐:qmcdump让你的加密音乐重获自由播放
  • 数据偏见:识别、规避与实战应对策略
  • Royal TSX中文汉化包:3分钟让专业远程管理工具说中文
  • 终极网盘下载加速指南:3步实现直链解析与高速文件传输
  • Maven与Gradle的区别
  • AI与大模型新闻日报 | 2026-05-31
  • 西安曲江家政服务怎么选?2026曲江家政公司评测与实战落地指南 - 资讯快报
  • 告别版本混乱!在Ubuntu 22.04上管理多个.NET SDK(8.0/6.0/7.0)的保姆级指南
  • AI赋能Web3营销:从数据洞察到个性化对话的实战指南
  • 5个创意用法解锁Parsec-vdd虚拟显示器的隐藏潜力
  • 新郑震捷再生资源:荥阳专业的废旧物资拆除公司有哪些 - LYL仔仔
  • OBS StreamFX:免费打造专业级直播画面的终极特效插件
  • 从N-gram到ChatGPT:语言模型的技术演进与核心原理剖析
  • 告别网盘限速烦恼:9大平台直链下载助手完全指南
  • 微信通讯录大扫除:如何用WechatRealFriends揪出那些悄悄删除你的“好友“
  • 如何高效实现抖音无水印视频下载:开源工具的完整实践指南
  • 别再死磕传统LOD了!用UE5的Nanite做开放世界,我踩过的坑和最佳实践
  • 别再死记硬背了!用这5个高频场景,帮你彻底搞懂Docker常用命令(附CentOS/Ubuntu实战)
  • 思源宋体完全指南:7种字重免费开源中文字体的跨平台应用方案