java 日志的数据脱敏的实现方法
数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏,数据库安全技术之一。
比如我们现在有个user表,含有名字,性别,邮箱,电话号码等字段,但是当查看这些数据时,我们又不希望这些数据被暴露,这时可以对这些数据进行脱敏处理,当然可以根据需要选择哪些字段需要脱敏,然后再输出,至于怎么选择的,是另外一回事了。
思路
1。在model层进行处理,直接重写get方法,在写一个getPlain获取明文方法。(缺点:数据库写入和json序列化传递时使用的都是密文)
2.利用日志组件过滤特定的key,去进行脱敏(缺点:对所有的日志输出全部要正则匹配,非常耗时。)
由1,2的利弊,肯定会选择1,然后考虑一种实现(在model层定义方法,获取它的一个复制类,复制类里面的信息都是脱敏的,日志输出时只输出复制对象),克服掉1的缺点
1.定义接口类
publicinterfaceNoSensitiveObj{ defaultTnoSensitiveObj(){ return(T)this; } }
2.实现类如果这个类没有敏感信息,只实现NoSensitiveObj,不需要实现里面的方法
publicclassUserimplementsNoSensitiveObj{ privateStringname; privateStringphone; privateStringemail; publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicStringgetPhone(){ returnphone; } publicvoidsetPhone(Stringphone){ this.phone=phone; } publicStringgetEmail(){ returnemail; } publicvoidsetEmail(Stringemail){ this.email=email; } @Override publicUsernoSensitiveObj(){ Usert; t=newUser(); t.setEmail(SensitiveInfoUtils.email(email)); t.setName(SensitiveInfoUtils.chineseName(name)); t.setPhone(SensitiveInfoUtils.mobilePhone(phone)); returnt; } }
3.工具类
publicclassSensitiveInfoUtils{ /** *[中文姓名]只显示第一个汉字,其他隐藏为2个星号<例子:李**> */ publicstaticStringchineseName(finalStringfullName){ if(StringUtils.isBlank(fullName)){ return""; } finalStringname=StringUtils.left(fullName,1); returnStringUtils.rightPad(name,StringUtils.length(fullName),"*"); } /** *[中文姓名]只显示第一个汉字,其他隐藏为2个星号<例子:李**> */ publicstaticStringchineseName(finalStringfamilyName,finalStringgivenName){ if(StringUtils.isBlank(familyName)||StringUtils.isBlank(givenName)){ return""; } returnchineseName(familyName+givenName); } /** *[身份证号]显示最后四位,其他隐藏。共计18位或者15位。<例子:*************5762> */ publicstaticStringidCardNum(finalStringid){ if(StringUtils.isBlank(id)){ return""; } returnStringUtils.left(id,3).concat(StringUtils .removeStart(StringUtils.leftPad(StringUtils.right(id,3),StringUtils.length(id),"*"),"***")); } /** *[固定电话]后四位,其他隐藏<例子:****1234> */ publicstaticStringfixedPhone(finalStringnum){ if(StringUtils.isBlank(num)){ return""; } returnStringUtils.leftPad(StringUtils.right(num,4),StringUtils.length(num),"*"); } /** *[手机号码]前三位,后四位,其他隐藏<例子:138******1234> */ publicstaticStringmobilePhone(finalStringnum){ if(StringUtils.isBlank(num)){ return""; } returnStringUtils.left(num,2).concat(StringUtils .removeStart(StringUtils.leftPad(StringUtils.right(num,2),StringUtils.length(num),"*"),"***")); } /** *[地址]只显示到地区,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****> * *@paramsensitiveSize *敏感信息长度 */ publicstaticStringaddress(finalStringaddress,finalintsensitiveSize){ if(StringUtils.isBlank(address)){ return""; } finalintlength=StringUtils.length(address); returnStringUtils.rightPad(StringUtils.left(address,length-sensitiveSize),length,"*"); } /** *[电子邮箱]邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com> */ publicstaticStringemail(finalStringemail){ if(StringUtils.isBlank(email)){ return""; } finalintindex=StringUtils.indexOf(email,"@"); if(index<=1){ returnemail; }else{ returnStringUtils.rightPad(StringUtils.left(email,1),index,"*") .concat(StringUtils.mid(email,index,StringUtils.length(email))); } } /** *[银行卡号]前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234> */ publicstaticStringbankCard(finalStringcardNum){ if(StringUtils.isBlank(cardNum)){ return""; } returnStringUtils.left(cardNum,6).concat(StringUtils.removeStart( StringUtils.leftPad(StringUtils.right(cardNum,4),StringUtils.length(cardNum),"*"),"******")); } /** *[公司开户银行联号]公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号<例子:12********> */ publicstaticStringcnapsCode(finalStringcode){ if(StringUtils.isBlank(code)){ return""; } returnStringUtils.rightPad(StringUtils.left(code,2),StringUtils.length(code),"*"); } }
4.测试
publicclassTest{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(Test.class); publicstaticvoidmain(String[]args){ Useruser=newUser(); user.setName("张三"); user.setPhone("18666218777"); user.setEmail("zhangsan@qq.com"); System.out.println(JSON.toJSONString(user.noSensitiveObj())); } }
结果
{"email":"z*******@qq.com","name":"张*","phone":"18******77"}
经过和同事讨论后,发现其实不需要这么复杂,只要在model的tostring方法中脱敏即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。