Herramientas [4] Desensibilización de registros

Prefacio

Con el desarrollo acelerado de la tecnología y la era de la información, especialmente en la era del 5G y el big data, la seguridad de la información se ha convertido gradualmente en un tema de mayor preocupación para las personas. Es particularmente importante proteger la información de privacidad personal para usuarios y miembros. Para la visualización y el almacenamiento de algunos datos confidenciales, los departamentos de seguridad de la empresa a menudo requieren cifrado o desensibilización. Almacenamiento encriptado MD5 de datos confidenciales, procesamiento de desensibilización de registros y front-end. Tales como: DNI, número de teléfono móvil, nombre, dirección, etc., especialmente industrias y empresas que requieren alta seguridad de datos sensibles; comercio electrónico, comunicaciones, finanzas y otras industrias.

Uno, kit de herramientas de registro

Hoy, hablo principalmente sobre el procesamiento de desensibilización de registros del sistema back-end para datos confidenciales y la clase de implementación de herramientas que está lista para usar. Usar el procesamiento de desensibilización de registros del kit de herramientas de registro es muy simple y conveniente. Principalmente dividido en los siguientes pasos:

  • Definir palabras clave de registro de enmascaramiento
  • Obtener la posición del índice de inicio de la palabra clave
  • Obtener la posición del índice final de la palabra clave
  • Desensibilización de palabras clave

Herramientas principales para el procesamiento de la desensibilización de troncos:

package **.util;

import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.google.common.collect.Lists;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: **
 * @Date: 2020/9/17 10:18
 * @param: 数据脱敏处理转换类【logback包】
 * @return:
 */
public class SensitiveDataConverter extends MessageConverter {

    /**
     * 日志脱敏开关
     */
    private static String converterCanRun = "true";
    /**
     * 日志脱敏关键字
     */
    private static String sensitiveDataKeys = "idcard,realname,bankcard,mobile,shipAddress,detailedAddr,customerName,shipAddriess";

    private static Pattern pattern = Pattern.compile("[0-9a-zA-Z]");

    @Override
    public String convert(ILoggingEvent event){
        // 获取原始日志
        String oriLogMsg = event.getFormattedMessage();

        // 获取脱敏后的日志
        String afterLogMsg = invokeMsg(oriLogMsg);
        return afterLogMsg;
    }
    /**
     * 处理日志字符串,返回脱敏后的字符串
     * @param: msg
     * @return
     */
    public static String invokeMsg(final String oriMsg){
        String tempMsg = oriMsg;
        if("true".equals(converterCanRun)){
            // 处理字符串
            if(sensitiveDataKeys != null && sensitiveDataKeys.length() > 0){
                String[] keysArray = sensitiveDataKeys.split(",");
                for(String key: keysArray){
                    int index= -1;
                    do{
                        index = tempMsg.indexOf(key, index+1);
                        if(index != -1){
                            // 判断key是否为单词字符
                            if(isWordChar(tempMsg, key, index)){
                                continue;
                            }
                            // 寻找值的开始位置
                            int valueStart = getValueStartIndex(tempMsg, index + key.length());

                            // 查找值的结束位置(逗号,分号)........................
                            int valueEnd = getValuEndEIndex(tempMsg, valueStart);

                            // 对获取的值进行脱敏
                            String subStr = tempMsg.substring(valueStart, valueEnd);
                            subStr = tuomin(subStr, key);
                            ///
                            tempMsg = tempMsg.substring(0,valueStart) + subStr + tempMsg.substring(valueEnd);
                        }
                    }while(index != -1);
                }
            }
        }
        return tempMsg;
    }

    /**
     * 判断从字符串msg获取的key值是否为单词
     * index为key在msg中的索引值
     * @return
     */
    private static boolean isWordChar(String msg, String key, int index){
        // 必须确定key是一个单词............................
        if(index != 0){ // 判断key前面一个字符
            char preCh = msg.charAt(index-1);
            Matcher match = pattern.matcher(preCh + "");
            if(match.matches()){
                return true;
            }
        }
        // 判断key后面一个字符
        char nextCh = msg.charAt(index + key.length());
        Matcher match = pattern.matcher(nextCh + "");
        if(match.matches()){
            return true;
        }
        return false;
    }

    /**
     * 获取value值的开始位置
     * @param msg 要查找的字符串
     * @param valueStart 查找的开始位置
     * @return
     */
    private static int getValueStartIndex(String msg, int valueStart ){
        // 寻找值的开始位置.................................
        do{
            char ch = msg.charAt(valueStart);
            if(ch == ':' || ch == '='){ // key与 value的分隔符
                valueStart ++;
                ch = msg.charAt(valueStart);
                if(ch == '"'){
                    valueStart ++;
                }
                break;    // 找到值的开始位置
            }else{
                valueStart ++;
            }
        }while(true);
        return valueStart;
    }

    /**
     * 获取value值的结束位置
     * @return
     */
    private static int getValuEndEIndex(String msg,int valueEnd){
        do{
            if(valueEnd == msg.length()){
                break;
            }
            char ch = msg.charAt(valueEnd);

            if(ch == '"'){ // 引号时,判断下一个值是结束,分号还是逗号决定是否为值的结束
                if(valueEnd+1 == msg.length()){
                    break;
                }
                char nextCh = msg.charAt(valueEnd+1);
                if(nextCh ==';' || nextCh == ','){
                    // 去掉前面的 \  处理这种形式的数据
                    while(valueEnd>0 ){
                        char preCh = msg.charAt(valueEnd-1);
                        if(preCh != '\\'){
                            break;
                        }
                        valueEnd--;
                    }
                    break;
                }else{
                    valueEnd ++;
                }
            }else if (ch ==';' || ch == ',' || ch == '}'){
                break;
            }else{
                valueEnd ++;
            }

        }while(true);
        return valueEnd;
    }

    /**
     *  调用脱敏工具类进行字段日志处理
     * @param submsg
     * @param key
     * @return
     */
    private static String tuomin(String submsg, String key){
        // idcard:身份证号, realname:姓名, bankcard:银行卡号, mobile:手机号,attribute10,shipAddress,detailedAddr:地址
        if("idcard".equals(key)){
            return SensitiveInfoUtils.idCardNum(submsg);
        }
        if(Lists.newArrayList("realname","customerName").equals(key)){
            return SensitiveInfoUtils.chineseName(submsg);
        }
        if("bankcard".equals(key)){
            return SensitiveInfoUtils.bankCard(submsg);
        }
        if("mobile".equals(key)){
            return SensitiveInfoUtils.mobilePhone(submsg);
        }
        if(Lists.newArrayList("attribute10","shipAddress","detailedAddr","shipAddriess").contains(key)){
            return SensitiveInfoUtils.address(submsg);
        }
        return "";
    }

    public static void main(String[] args) {
        String tempMsg = "{sign=f88898b2677e62f1ad54b9e330c0a27e, idcard=130333198901192762, realname=%E5%BE%90%E5%BD%A6%E5%A8%9C, key=c5d34d4c3c71cc45c88f32b4f13da887, mobile=13210141605, bankcard=6226430106137525}";
        String tempMsg1 = "{\"reason\":\"成功 \",\"result\":{\"jobid\":\"JH2131171027170837443588J6\",\"realname\":\"李哪娜\",\"bankcard\":\"6226430106137525\",\"idcard\":\"130333198901192762\",\"mobile\":\"13210141605\",\"res\":\"1\",\"message\":\"验证成功\"},\"error_code\":0}";
        String shipAddress ="{shipAddress=宁夏回族自治区.银川市.金凤区.长城中路街道收货人:+卜广龙手机号码:+13992283627}";
        String detailedAddr ="{\"attribute10\":\"浙江省.杭州市.桐庐县.桐君街道.收货人: 陈静手机号码: 15168393010所在地区: 浙江省杭州市桐庐县城南街道详细地址: 白云源路1618号银通汽车4楼\"}";
        SensitiveDataConverter sc = new SensitiveDataConverter();
        System.out.println(sc.invokeMsg(tempMsg));
        System.out.println(sc.invokeMsg(tempMsg1));
        System.out.println(sc.invokeMsg(shipAddress));
        System.out.println(sc.invokeMsg(detailedAddr));
    }
}

Dos, herramientas de procesamiento de palabras clave

Individualice las palabras clave que deben desensibilizarse. También puede definir un método para pasar de forma dinámica las palabras clave para la desensibilización:

package com.vip.fcs.app.ar.util;

import org.apache.commons.lang3.StringUtils;

/**
 * @Author: **
 * @Date: 2020/9/17 10:23
 * @param: 数据脱敏处理工具类
 * @return:
 */
public class SensitiveInfoUtils {

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

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

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

    /**
     * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234>
     *
     * @param cardNum
     * @return
     */
    public static String bankCard(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个星号<例子:广东省广州市*******>
     *
     * @param:cardNum
     * @return
     */
    public static String address(String address) {
        if (StringUtils.isBlank(address) || address.length() <9) {
            return "";
        }
        String name = StringUtils.left(address, 9);
        return StringUtils.rightPad(name, StringUtils.length(address), "*********");
    }

}

 

Supongo que te gusta

Origin blog.csdn.net/follow_24/article/details/108652118
Recomendado
Clasificación