java 日志的数据脱敏的实现方法

 更新时间:2019年01月03日 11:29:14   作者:阳光11  
今日给大家介绍一下java 日志的数据脱敏的实现方法,可以更好的保护数据的安全,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏,数据库安全技术之一。

比如我们现在有个user表,含有名字,性别,邮箱,电话号码等字段,但是当查看这些数据时,我们又不希望这些数据被暴露,这时可以对这些数据进行脱敏处理,当然可以根据需要选择哪些字段需要脱敏,然后再输出,至于怎么选择的,是另外一回事了。

思路

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

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

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

1.定义接口类

public interface NoSensitiveObj<T> {

 default T noSensitiveObj(){
  return (T) this;
 }
}

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

public class User implements NoSensitiveObj<User>{

 private String name;
 
 private String phone;
 
 private String email;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getPhone() {
  return phone;
 }

 public void setPhone(String phone) {
  this.phone = phone;
 }

 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 @Override
 public User noSensitiveObj() {
   User t;
   t=new User();
   t.setEmail(SensitiveInfoUtils.email(email));
   t.setName(SensitiveInfoUtils.chineseName(name));
   t.setPhone(SensitiveInfoUtils.mobilePhone(phone));
  return t;
 }
 
}

3.工具类

public class SensitiveInfoUtils {

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

 /**
  * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**>
  */
 public static String chineseName(final String familyName, final String givenName) {
  if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) {
   return "";
  }
  return chineseName(familyName + givenName);
 }

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

  return StringUtils.left(id, 3).concat(StringUtils
    .removeStart(StringUtils.leftPad(StringUtils.right(id, 3), StringUtils.length(id), "*"), "***"));
 }

 /**
  * [固定电话] 后四位,其他隐藏<例子:****1234>
  */
 public static String fixedPhone(final String num) {
  if (StringUtils.isBlank(num)) {
   return "";
  }
  return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
 }

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

 }

 /**
  * [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****>
  *
  * @param sensitiveSize
  *   敏感信息长度
  */
 public static String address(final String address, final int sensitiveSize) {
  if (StringUtils.isBlank(address)) {
   return "";
  }
  final int length = StringUtils.length(address);
  return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");
 }

 /**
  * [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com>
  */
 public static String email(final String email) {
  if (StringUtils.isBlank(email)) {
   return "";
  }
  final int index = StringUtils.indexOf(email, "@");
  if (index <= 1) {
   return email;
  } else {
   return StringUtils.rightPad(StringUtils.left(email, 1), index, "*")
     .concat(StringUtils.mid(email, index, StringUtils.length(email)));
  }
 }

 /**
  * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234>
  */
 public static String bankCard(final 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个星号<例子:12********>
  */
 public static String cnapsCode(final String code) {
  if (StringUtils.isBlank(code)) {
   return "";
  }
  return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");
 }

}

4.测试

public class Test {

 private static final Logger logger=LoggerFactory.getLogger(Test.class);
 
 public static void main(String[] args) {
  User user=new User();
  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 方法中脱敏即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 如何使用XPath提取xml文档数据

    如何使用XPath提取xml文档数据

    这篇文章主要介绍了如何使用XPath提取xml文档数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Java由浅入深刨析继承

    Java由浅入深刨析继承

    继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为
    2022-03-03
  • Java NIO与IO的区别以及比较

    Java NIO与IO的区别以及比较

    这篇文章主要介绍了Java NIO与IO的区别以及比较,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 浅谈java web中常用对象对应的实例化接口

    浅谈java web中常用对象对应的实例化接口

    下面小编就为大家带来一篇浅谈java web中常用对象对应的实例化接口。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Mybatis-Plus实现公共字段自动赋值的方法

    Mybatis-Plus实现公共字段自动赋值的方法

    这篇文章主要介绍了Mybatis-Plus实现公共字段自动赋值的方法,涉及到通用字段自动填充的最佳实践总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Java实现将列表数据导出为PDF文件并添加水印

    Java实现将列表数据导出为PDF文件并添加水印

    这篇文章主要为大家详细介绍了如何使用Java实现把列表数据导出为PDF文件,同时加上PDF水印,文中的示例代码讲解详细,需要的可以参考下
    2024-02-02
  • 使用BindingResult 自定义错误信息

    使用BindingResult 自定义错误信息

    这篇文章主要介绍了使用BindingResult 自定义错误信息,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 史上最全的IDEA快捷键总结

    史上最全的IDEA快捷键总结

    这篇文章主要介绍了史上最全的IDEA快捷键总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • spring aop action中验证用户登录状态的实例代码

    spring aop action中验证用户登录状态的实例代码

    本篇文章主要介绍了spring aop action中验证用户登录状态的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Java并发之Semaphore工具类r的全面解析

    Java并发之Semaphore工具类r的全面解析

    Semaphore 是 java.util.concurrent中非常有用的并发编程工具类,它通常被用于限制对某个资源或资源池的并发访问数量,下面我们就来深入了解一下Semaphore的具体使用吧
    2024-02-02

最新评论