数据脱敏,参照阿里脱敏规则与国规

数据脱敏,参照阿里脱敏规则与国规

阿里巴巴脱敏规则
阿里巴巴的脱敏规则
国家规则
国家规则

我的思路是把字段代码(脱敏字段英文名),字段脱敏方式保存到数据库,一次性通过缓存读取,然后所有操作都在缓存进行,有修改数据的操作时修改缓存同步修改到数据库……当然这跟本文标题没啥关系就让我冒个泡.

关于脱敏方面,主要需要的参数是脱敏内容和方式,这个很简单,但是都是在代码中完成的,如果把所有字段的脱敏具体规则存到xml文件中,通过读取xml文件节点来反射类和方法,就提高了可拓展性(虽然我认为这个拓展性没啥大用)

首先是脱敏规则的xml文件

<?xml version="1.0" encoding="UTF-8"?>

<!-- type:0:阿里巴巴规则/1:国家规则 -->

<rules objectName="com.hanweb.cas.util.desensitize.DesentilizeUtil">

<!-- 所有method为reveal的为正则表达式脱敏 -->
<!-- regex为正则,desensilizeRule为替换 -->
<!--  此部分可扩展  -->

    <rule id="identifyCode" fieldName="身份证" method="reveal">
        <regex type="0" regex="(\d{1})\d+(\w{1})" desensilizeRule="$1***********$2"/>
        <regex type="1" regex="\d+(\w{4})" desensilizeRule="***********$1"/>
    </rule>


    <rule id="phoneNumber" fieldName="手机号" method="reveal">
        <regex type="0" regex="(\d{3})\d{6}(\d{2})" desensilizeRule="$1***********$2"/>
        <regex type="1" regex="(\d{3})\d{5}(\d{4})" desensilizeRule="$1***********$2"/>
    </rule>


    <rule id="email" fieldName="邮箱" method="reveal">
        <regex type="0" regex="(\w{3})\w+@(\w+)" desensilizeRule="$1***********$2"/>
        <regex type="1" regex="(\w{1})\w+@(\w+)" desensilizeRule="***********$2"/>
    </rule>


    <rule id="count" fieldName="支付宝/微信号" method="reveal">
        <regex type="0" />
        <regex type="1" regex="\d+(\w{4})" desensilizeRule="*******$1"/>
    </rule>

	 
	
	 

<!--  所有method为round的为显示前后各多少个字符  -->
<!--   regex为开头显示多少,desensilizeRule为结尾显示多少  -->
    <!--  此部分可扩展  -->


    <rule id="passport" fieldName="护照" method="round">
        <regex type="0"  regex="1" desensilizeRule="1" />
        <regex type="1"  />
    </rule>
 
	<rule id="vehicleEngineNumber" fieldName="车辆发动机编号" method="round">
        <regex type="0"  regex="1" desensilizeRule="2" />
        <regex type="1"  />
    </rule>

	<rule id="vehicleFrameNumber" fieldName="车辆车架号" method="round">
        <regex type="0"  regex="3" desensilizeRule="3" />
        <regex type="1"  />
    </rule>

	<rule id="plateNumber" fieldName="车牌号" method="round">
        <regex type="0"  regex="2" desensilizeRule="3" />
        <regex type="1"  />
    </rule>

	<rule id="dateTime" fieldName="日期" method="round">
        <regex type="0"   />
        <regex type="1"  regex="0" desensilizeRule="4"/>
    </rule>

	<rule id="nickName" fieldName="昵称" method="round">
        <regex type="0"   regex="1" desensilizeRule="1"/>
        <regex type="1"  />
    </rule>
   
    <rule id="HMPhone" fieldName="港澳手机号" method="round">
        <regex type="0" regex="2" desensilizeRule="2"/>
        <regex type="1" />
    </rule>

	 <rule id="TPhone" fieldName="台湾手机号" method="round">
        <regex type="0" regex="2" desensilizeRule="3"/>
        <regex type="1" />
    </rule>


<!--  所有method以handle开头的为单独方法  -->
<!--   regex与type同值,desensilizeRule不用  -->
<!--  此部分不可扩展  -->

   <rule id="address" fieldName="地址" method="handleAddress">
        <regex type="0" regex="0" desensilizeRule=""/>
        <regex type="1" regex="1" desensilizeRule="" />
    </rule>

	  <rule id="name" fieldName="中文姓名" method="handleName">
        <regex type="0" regex="0" desensilizeRule=""/>
        <regex type="1" regex="1" desensilizeRule="" />
    </rule>

	<rule id="securityCard" fieldName="社保卡/医保卡" method="handleSecurityCard">
        <regex type="0"  />
        <regex type="1" />
    </rule>

	 <rule id="Tel" fieldName="固定电话" method="handleTel">
        <regex type="0" />
        <regex type="1" />
    </rule>

    <rule id="Tel" fieldName="固定电话" method="handleTel">
        <regex type="0" />
        <regex type="1" />
    </rule>



    <rule id="overSeaTel" fieldName="海外号码" method="handleOverSeaTel">
        <regex type="0" regex="0" />
        <regex type="1" />
    </rule>


    <rule id="other" fieldName="其他" method="">
        <regex type="0"  regex=""/>
        <regex type="1"  regex=""/>
    </rule>
</rules>

id是字段名,method是反射的方法名,反射类在根节点

然后需要读取xml文件获取节点,这里主要使用jsoup,然后需要一个容器……实体类来存储读取的信息方便调用



/**
 * @Description:
 * @author: amethyst
 * @date: 2019-11-16 11:56
 * @update_by:
 * @tags:
 */
public class Rules {

    /**
     * 字段代码
     */
    private String fieldCode;

    /**
     * 字段名
     */
    private String fielName;

    /**
     * 函数名
     */
    private String method;

    /**
     * 脱敏方式
     */
    private int type;

    public String getFieldCode() {
        return fieldCode;
    }

    public void setFieldCode(String fieldCode) {
        this.fieldCode = fieldCode;
    }

    public String getFielName() {
        return fielName;
    }

    public void setFielName(String fielName) {
        this.fielName = fielName;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

读取xml节点信息

import  org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import java.io.FileNotFoundException;

/**
 * 
 * @Description: 根据xml脱敏规则反射
 * @author: amethyst
 * @date: 2019-11-16 15:18
 * @update_by:
 * @tags:
 */
@Service
public class RuleService {
    /**
     *  XML文件路径
     */
    private static Document xmlDoc;

    /**
     * 反射对象
     */
    private static String reflectObject;

    /**
     * 正则
     */
    private String regex;

    /**
     * 替换
     */
    private String desensilizeRule;

    public  String getReflectObject() {
        return reflectObject;
    }

    public String getRegex() {
        return regex;
    }

    public void setRegex(String regex) {
        this.regex = regex;
    }

    public String getDesensilizeRule() {
        return desensilizeRule;
    }

    public void setDesensilizeRule(String desensilizeRule) {
        this.desensilizeRule = desensilizeRule;
    }

    static {
        try {
        	
        	
            String xml= FileUtils.readFileToString( ResourceUtils.getFile("classpath:desensitize-rules.xml"));
            xmlDoc = Jsoup.parse(xml, "", Parser.xmlParser());
            reflectObject=xmlDoc.select("rules").attr("objectName");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 获取xml脱敏信息
     * @Author: Amethyst
     * @Params: [fieldCode, type]
     * @return: com.hanweb.cas.entity.desensitize.Rules
     * @Date: 2019/11/18 11:28
     * @Update by:
     */
    public Rules getRule(String fieldCode,int type){
        Rules rules=new Rules();
        Elements rule = xmlDoc.select("#"+fieldCode);
        rules.setFieldCode(fieldCode);
        rules.setFielName(rule.select("rule").attr("fieldName"));
        rules.setMethod(rule.select("rule").attr("method"));
        rules.setType(type);
        Elements regex=rule.select("regex").eq(type);
        this.setRegex(regex.select("regex").attr("regex"));
        this.setDesensilizeRule(regex.select("regex").attr("desensilizeRule"));
        return  rules;
    }

}

接下来就是对xml文件里方法的实现




/**
 * @Notes: 这里的StringUtil和NumberUtil为自己写的工具类,实际只是分割字符和String转int而以,请自行修改
 * @Description: 脱敏工具类
 * @author: amethyst
 * @date: 2019-11-14 16:37
 * @update_by:
 * @tags:
 */
public class DesentilizeUtil {

    /**
     * 阿里巴巴标准
     */
    public static final int ALIBABA=0;

    /**
     * 国标
     */
    public static final int NATION=1;


    public String reveal(String content,String regex,String desensilizeRule){
        return content.replaceAll(regex,desensilizeRule);
    }

        public  String round(String content,String first,String last){
        int index= NumberUtil.getInt(first);
        int end=NumberUtil.getInt(last);
        String hideContent=revealRound(content,index,end);
        return hideContent;
    }

        public  String handleName(String name,String ruleType,String b){

        String handledName=name;
            int len=name.length();
            if (len<3){
                handledName=DesentilizeUtil.revealRight(name,1);
            }else {
                handledName=DesentilizeUtil.revealRight(name,2);
            }
        return  handledName;
    }


    public static String handleAddress(String address,String ruleType,String b){

        int rule=NumberUtil.getInt(ruleType);
        String handledAddress=address;
        if (rule==0){
            String[] temp=StringUtil.split(address,"区");
            temp[1]=DesentilizeUtil.revealLeft(temp[1],0);
            handledAddress=temp[0]+"区"+temp[1];
        }else if (rule==1){
            if (address.length()>=12){
                handledAddress=revealLeft(address,6);
            }else {
                handledAddress=revealLeft(address,address.length()/2-1);
            }
        }else {
            handledAddress=address;
        }
        return  handledAddress;
    }


    public String handleSecurityCard(String content,String ruleType,String b){
        int rule=NumberUtil.getInt(ruleType);
        String handledSecurityCard=content;
        int len=content.length();
        if (rule==0){
            if (len%3==0){
                handledSecurityCard=round(content,len/3+"",len/3+"");
            }else {
                handledSecurityCard=round(content,len/3+1+"",len/3+"");
            }
        }
        if (rule==1){
            handledSecurityCard=round(content, 0+"",4+"");
        }
        return handledSecurityCard;
    }

    public String handleTel(String content,String ruleType,String b){
        int rule=NumberUtil.getInt(ruleType);
        String handledTel=content;
        if (rule==0){
            try {
                String temp[]=content.split("-");
                temp[1]=revealRight(temp[1],4);
                handledTel=temp[0]+"-"+temp[1];
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return handledTel;
    }

    public String handleOverSeaTel(String content,String ruleType,String b){
        int rule=NumberUtil.getInt(ruleType);
        String handledOverSeaTel=content;
        if (rule==0){
            try {
                String temp[]=handledOverSeaTel.split("-");
                handledOverSeaTel=temp[0]+"-"+temp[1]+"-"+temp[2].replaceAll("\\d+(\\d{4})\\d{2}","***$1***");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return handledOverSeaTel;
    }




    public static String revealLeft(String fieldContent, int index){
        String hideContent=StringUtils.left(fieldContent,index);
        return StringUtils.rightPad(hideContent,StringUtils.length(fieldContent),"*");
    }

    public  static String revealRight(String fieldContent,int end){
        String hideContent=StringUtils.right(fieldContent,end);
        return StringUtils.leftPad(hideContent,StringUtils.length(fieldContent),"*");
    }


    public  static String revealRound(String fieldContent,int index,int end){
        String hideContent=StringUtils.left(fieldContent, index).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(fieldContent, end),
                StringUtils.length(fieldContent), "*"), "***"));
        return hideContent;
    }

}

准备得差不多了,下面就是通过获取参数反射调用方法


import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Description: 根据xml信息反射
 * @author: amethyst
 * @date: 2019-11-16 11:26
 * @update_by:
 * @tags:
 */
public class InstenceUtil {

    public  static String invokeMethod(String object,String methodName,Class<?>[] parameterTypes,Object[] args){
        String result=null;
        try {
            Class<?> objectClass = Class.forName(object);
            Object entity= objectClass.newInstance();
            Method method=objectClass.getMethod(methodName,parameterTypes);
            result = (String) method.invoke(entity,args);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }
}

我专写了一个类来存储调用方法时的字段代码和选择规则‘

/**

@Description:

@author: Amethyst

@date: 2019-11-18 10:25

@update_by:

@tags:
*/
public class SelectRule {

private String filedCode;

private int type;

public String getFiledCode() {
return filedCode;
}

public void setFiledCode(String filedCode) {
this.filedCode = filedCode;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}
}

接下来就是根据xml的脱敏信息来反射了

package com.hanweb.cas.service.desensitize;

import com.hanweb.cas.entity.desensitize.Rules;
import com.hanweb.common.util.FileUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import java.io.FileNotFoundException;

/**
 * @Description: 根据xml脱敏规则反射
 * @author: amethyst
 * @date: 2019-11-16 15:18
 * @update_by:
 * @tags:
 */
@Service
public class RuleService {
    /**
     *  XML文件路径
     */
    private static Document xmlDoc;

    /**
     * 反射对象
     */
    private static String reflectObject;

    /**
     * 正则
     */
    private String regex;

    /**
     * 替换
     */
    private String desensilizeRule;

    public  String getReflectObject() {
        return reflectObject;
    }

    public String getRegex() {
        return regex;
    }

    public void setRegex(String regex) {
        this.regex = regex;
    }

    public String getDesensilizeRule() {
        return desensilizeRule;
    }

    public void setDesensilizeRule(String desensilizeRule) {
        this.desensilizeRule = desensilizeRule;
    }

    static {
        try {
            String xml= FileUtil.readFileToString( ResourceUtils.getFile("classpath:desensitize-rules.xml"));
            xmlDoc = Jsoup.parse(xml, "", Parser.xmlParser());
            reflectObject=xmlDoc.select("rules").attr("objectName");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 获取xml脱敏信息
     * @Author: Amethyst
     * @Params: [fieldCode, type]
     * @return: com.hanweb.cas.entity.desensitize.Rules
     * @Date: 2019/11/18 11:28
     * @Update by:
     */
    public Rules getRule(String fieldCode,int type){
        Rules rules=new Rules();
        Elements rule = xmlDoc.select("#"+fieldCode);
        rules.setFieldCode(fieldCode);
        rules.setFielName(rule.select("rule").attr("fieldName"));
        rules.setMethod(rule.select("rule").attr("method"));
        rules.setType(type);
        Elements regex=rule.select("regex").eq(type);
        this.setRegex(regex.select("regex").attr("regex"));
        this.setDesensilizeRule(regex.select("regex").attr("desensilizeRule"));
        return  rules;
    }

}

最后的调用是最简单的


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Description: 信息脱敏
 * @author: Amethyst
 * @date: 2019-11-18 10:24
 * @update_by:
 * @tags:
 */
public class DesensitilizeRpcService{

    private DoDesensilize doDesensilize=new DoDesensilize();

    public String desensitize(String content, SelectRule rule) {
        String s=null;
       s=doDesensilize.doDesensilize(content,rule);
        return s;
    }
}

  • 8
    点赞
  • 33
    收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想当房东的小男孩

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值