java 日志的數(shù)據(jù)脫敏的實(shí)現(xiàn)方法
數(shù)據(jù)脫敏是指對(duì)某些敏感信息通過(guò)脫敏規(guī)則進(jìn)行數(shù)據(jù)的變形,實(shí)現(xiàn)敏感隱私數(shù)據(jù)的可靠保護(hù)。在涉及客戶(hù)安全數(shù)據(jù)或者一些商業(yè)性敏感數(shù)據(jù)的情況下,在不違反系統(tǒng)規(guī)則條件下,對(duì)真實(shí)數(shù)據(jù)進(jìn)行改造并提供測(cè)試使用,如身份證號(hào)、手機(jī)號(hào)、卡號(hào)、客戶(hù)號(hào)等個(gè)人信息都需要進(jìn)行數(shù)據(jù)脫敏,數(shù)據(jù)庫(kù)安全技術(shù)之一。
比如我們現(xiàn)在有個(gè)user表,含有名字,性別,郵箱,電話號(hào)碼等字段,但是當(dāng)查看這些數(shù)據(jù)時(shí),我們又不希望這些數(shù)據(jù)被暴露,這時(shí)可以對(duì)這些數(shù)據(jù)進(jìn)行脫敏處理,當(dāng)然可以根據(jù)需要選擇哪些字段需要脫敏,然后再輸出,至于怎么選擇的,是另外一回事了。
思路
1。在 model層進(jìn)行處理,直接重寫(xiě)get方法,在寫(xiě)一個(gè)getPlain 獲取明文方法。(缺點(diǎn):數(shù)據(jù)庫(kù)寫(xiě)入和json序列化傳遞時(shí)使用的都是密文)
2.利用 日志組件過(guò)濾 特定的key,去進(jìn)行脫敏(缺點(diǎn):對(duì)所有的日志輸出全部要正則匹配,非常耗時(shí)。)
由1,2的利弊,肯定會(huì)選擇1,然后考慮一種實(shí)現(xiàn)(在model層定義方法,獲取它的一個(gè)復(fù)制類(lèi),復(fù)制類(lèi)里面的信息都是脫敏的,日志輸出時(shí)只輸出 復(fù)制對(duì)象),克服掉1的缺點(diǎn)
1.定義接口類(lèi)
public interface NoSensitiveObj<T> {
default T noSensitiveObj(){
return (T) this;
}
}
2.實(shí)現(xiàn)類(lèi) 如果這個(gè)類(lèi)沒(méi)有敏感信息,只實(shí)現(xiàn) NoSensitiveObj ,不需要實(shí)現(xiàn)里面的方法
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.工具類(lèi)
public class SensitiveInfoUtils {
/**
* [中文姓名] 只顯示第一個(gè)漢字,其他隱藏為2個(gè)星號(hào)<例子:李**>
*/
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), "*");
}
/**
* [中文姓名] 只顯示第一個(gè)漢字,其他隱藏為2個(gè)星號(hào)<例子:李**>
*/
public static String chineseName(final String familyName, final String givenName) {
if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) {
return "";
}
return chineseName(familyName + givenName);
}
/**
* [身份證號(hào)] 顯示最后四位,其他隱藏。共計(jì)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), "*");
}
/**
* [手機(jī)號(hào)碼] 前三位,后四位,其他隱藏<例子: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), "*"), "***"));
}
/**
* [地址] 只顯示到地區(qū),不顯示詳細(xì)地址;我們要對(duì)個(gè)人信息增強(qiáng)保護(hù)<例子:北京市海淀區(qū)****>
*
* @param sensitiveSize
* 敏感信息長(zhǎng)度
*/
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è)字母,前綴其他隱藏,用星號(hào)代替,@及后面的地址顯示<例子: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)));
}
}
/**
* [銀行卡號(hào)] 前六位,后四位,其他用星號(hào)隱藏每位1個(gè)星號(hào)<例子: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), "*"), "******"));
}
/**
* [公司開(kāi)戶(hù)銀行聯(lián)號(hào)] 公司開(kāi)戶(hù)銀行聯(lián)行號(hào),顯示前兩位,其他用星號(hào)隱藏,每位1個(gè)星號(hào)<例子:12********>
*/
public static String cnapsCode(final String code) {
if (StringUtils.isBlank(code)) {
return "";
}
return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");
}
}
4.測(cè)試
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()));
}
}
結(jié)果
{"email":"z*******@qq.com","name":"張*","phone":"18******77"}
經(jīng)過(guò)和同事討論后,發(fā)現(xiàn)其實(shí)不需要這么復(fù)雜,只要在model 的tostring 方法中脫敏即可。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口
下面小編就為大家?guī)?lái)一篇淺談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
Mybatis-Plus實(shí)現(xiàn)公共字段自動(dòng)賦值的方法
這篇文章主要介紹了Mybatis-Plus實(shí)現(xiàn)公共字段自動(dòng)賦值的方法,涉及到通用字段自動(dòng)填充的最佳實(shí)踐總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Java實(shí)現(xiàn)將列表數(shù)據(jù)導(dǎo)出為PDF文件并添加水印
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)把列表數(shù)據(jù)導(dǎo)出為PDF文件,同時(shí)加上PDF水印,文中的示例代碼講解詳細(xì),需要的可以參考下2024-02-02
spring aop action中驗(yàn)證用戶(hù)登錄狀態(tài)的實(shí)例代碼
本篇文章主要介紹了spring aop action中驗(yàn)證用戶(hù)登錄狀態(tài)的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Java并發(fā)之Semaphore工具類(lèi)r的全面解析
Semaphore 是 java.util.concurrent中非常有用的并發(fā)編程工具類(lèi),它通常被用于限制對(duì)某個(gè)資源或資源池的并發(fā)訪問(wèn)數(shù)量,下面我們就來(lái)深入了解一下Semaphore的具體使用吧2024-02-02

