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

