java 日志的數據脫敏


思路 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 方法中脫敏即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM