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方法中脱敏即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。