java 日志的数据脱敏

思路 1。在 model层进行处理,直接重写get方法,在写一个getPlain 获取明文方法。(缺点:数据库写入和json序列化传递时使用的都是密文)

  2.利用 日志组件过滤 特定的key,去进行脱敏(缺点:对所有的日志输出全部要正则匹配,非常耗时。)

由1,2的利弊,肯定会选择1,然后考虑一种实现(在model层定义方法,获取它的一个复制类,复制类里面的信息都是脱敏的,日志输出时只输出 复制对象),克服掉1的缺点  

1.定义接口类

1public interface NoSensitiveObj<T> { 2 3 default T noSensitiveObj(){ 4 return (T) this; 5 } 6}

2.实现类 如果这个类没有敏感信息,只实现 NoSensitiveObj ,不需要实现里面的方法

1public class User implements NoSensitiveObj<User>{ 2 3 private String name; 4 5 private String phone; 6 7 private String email; 8 9 public String getName() { 10 return name; 11 } 12 13 public void setName(String name) { 14 this.name = name; 15 } 16 17 public String getPhone() { 18 return phone; 19 } 20 21 public void setPhone(String phone) { 22 this.phone = phone; 23 } 24 25 public String getEmail() { 26 return email; 27 } 28 29 public void setEmail(String email) { 30 this.email = email; 31 } 32 33 @Override 34 public User noSensitiveObj() { 35 User t; 36 t=new User(); 37 t.setEmail(SensitiveInfoUtils.email(email)); 38 t.setName(SensitiveInfoUtils.chineseName(name)); 39 t.setPhone(SensitiveInfoUtils.mobilePhone(phone)); 40 return t; 41 } 42 43}

3.工具类

1public class SensitiveInfoUtils { 2 3 /** 4 * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**> 5 */ 6 public static String chineseName(final String fullName) { 7 if (StringUtils.isBlank(fullName)) { 8 return ""; 9 } 10 final String name = StringUtils.left(fullName, 1); 11 return StringUtils.rightPad(name, StringUtils.length(fullName), "*"); 12 } 13 14 /** 15 * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**> 16 */ 17 public static String chineseName(final String familyName, final String givenName) { 18 if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) { 19 return ""; 20 } 21 return chineseName(familyName + givenName); 22 } 23 24 /** 25 * [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。<例子:*************5762> 26 */ 27 public static String idCardNum(final String id) { 28 if (StringUtils.isBlank(id)) { 29 return ""; 30 } 31 32 return StringUtils.left(id, 3).concat(StringUtils 33 .removeStart(StringUtils.leftPad(StringUtils.right(id, 3), StringUtils.length(id), "*"), "***")); 34 } 35 36 /** 37 * [固定电话] 后四位,其他隐藏<例子:****1234> 38 */ 39 public static String fixedPhone(final String num) { 40 if (StringUtils.isBlank(num)) { 41 return ""; 42 } 43 return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"); 44 } 45 46 /** 47 * [手机号码] 前三位,后四位,其他隐藏<例子:138******1234> 48 */ 49 public static String mobilePhone(final String num) { 50 if (StringUtils.isBlank(num)) { 51 return ""; 52 } 53 return StringUtils.left(num, 2).concat(StringUtils 54 .removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "***")); 55 56 } 57 58 /** 59 * [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****> 60 * 61 * @param sensitiveSize 62 * 敏感信息长度 63 */ 64 public static String address(final String address, final int sensitiveSize) { 65 if (StringUtils.isBlank(address)) { 66 return ""; 67 } 68 final int length = StringUtils.length(address); 69 return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*"); 70 } 71 72 /** 73 * [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com> 74 */ 75 public static String email(final String email) { 76 if (StringUtils.isBlank(email)) { 77 return ""; 78 } 79 final int index = StringUtils.indexOf(email, "@"); 80 if (index <= 1) { 81 return email; 82 } else { 83 return StringUtils.rightPad(StringUtils.left(email, 1), index, "*") 84 .concat(StringUtils.mid(email, index, StringUtils.length(email))); 85 } 86 } 87 88 /** 89 * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234> 90 */ 91 public static String bankCard(final String cardNum) { 92 if (StringUtils.isBlank(cardNum)) { 93 return ""; 94 } 95 return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart( 96 StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******")); 97 } 98 99 /** 100 * [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号<例子:12********> 101 */ 102 public static String cnapsCode(final String code) { 103 if (StringUtils.isBlank(code)) { 104 return ""; 105 } 106 return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*"); 107 } 108 109}

4.测试

1public class Test { 2 3 private static final Logger logger=LoggerFactory.getLogger(Test.class); 4 5 public static void main(String[] args) { 6 User user=new User(); 7 user.setName("张三"); 8 user.setPhone("18666218777"); 9 user.setEmail("zhangsan@qq.com"); 10 System.out.println(JSON.toJSONString(user.noSensitiveObj())); 11 12 } 13}

结果

{"email":"z*******@qq.com","name":"张*","phone":"18******77"}

经过和同事讨论后,发现其实不需要这么复杂,只要在model 的tostring 方法中脱敏即可。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript日期

日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前