常用數據脫敏解決方案

數據脫敏的應用場景主要有2類:

  1. 接口返回數據
  2. 日誌打印數據

針對上述場景的需求,數據脫敏的實現方法可以有如下3種:

  1. 基於SQL進行脫敏,保證查詢到的結果就是脫敏信息:SQL需要精心設計,依賴數據庫函數,性能不高。
  2. 應用層脫敏:將查詢到數據根據一定的策略進行脫敏後再返回或打印日誌,對應用代碼有入侵,性能可控。
  3. 基於日誌框架進行脫敏:使用正則表達式進行處理,對日誌格式有要求,否則無法識別需要脫敏的信息。

基於SQL語句脫敏

基於SQL語句的數據脫敏,需要依賴相應的數據庫函數。
如下,以MySQL數據庫爲例,在查詢數據的時候通過函數concat()left()right()實現脫敏處理。

-- 通過SQL語句對查詢結果進行脫敏處理
select 
concat(left(mobile,3),'********') as mobile_desensitive,
concat(left(idcard,5),'*********',right(idcard,4)) as idcard_desensitive 
from `user` u; 

查詢結果如下:

mobile_desensitive|idcard_desensitive|
------------------+------------------+
132********       |53211*********1111|
153********       |11011*********1111|

基於SQL語句的數據脫敏處理,SQL語句需要精心設計,並且需要依賴數據庫函數,同時也可能存在性能瓶頸。
在數據規模可控時可以使用,否則建議使用其他方案。

應用層脫敏

數據脫敏的處理完全在應用層處理,也就說:什麼數據該脫敏,如何脫敏,脫敏後如何使用完全在應用層控制。
在應用層進行數據脫敏可以應對日誌打印,API接口數據返回等場景需求。
組件sensitive-plus提供了完整的解決方案。

字符串脫敏

// 調用工具方法對字符串進行脫敏
String mobile = "15678900987";
String sensitive = SensitiveInfoUtils.mobilePhone(mobile);
System.out.println(String.format("%s\n%s", source, sensitive));

輸出:

15678900987
156****0987

對象屬性脫敏

// 調用工具方法實現對象屬性脫敏
String chineseName = "趙子龍";
String mobile = "13242429876";
String fixPhone = "010-32342214";
String address = "西川成都蜀國大將軍府";
String idCard = "123456789012345678";
String bankCard = "6666666666666666666";
String email = "[email protected]";
String password = "1234567890";

SimpleEntity entity = SimpleEntity.builder()
        .chineseName(chineseName)
        .mobile(mobile)
        .fixPhone(fixPhone)
        .address(address)
        .idCard(idCard)
        .bankCard(bankCard)
        .email(email)
        .password(password)
        .build();
Object desensitive = SensitiveInfoUtils.desensitive(entity);
System.out.println(JSON.toJSONString(desensitive));

輸出:

{
	"chineseName": "趙**",
	"mobile": "132****9876",
	"fixPhone": "********2214",
	"address": "西川成都******",
	"idCard": "**************5678",
	"bankCard": "666666*********6666",
	"email": "z*********@chengdu.com",
	"password": "******"
}

或者直接調用JSON脫敏序列化方法:

System.out.println(SensitiveJsonUtils.toJson(entity));

注:該方式需要在對象實體上應用脫敏註解。

public class SimpleEntity {
    /** 中文姓名 */
    @SensitiveLengthChineseName
    String chineseName;

    /** 手機號 */
    @SensitiveLengthMobile
    String mobile;

    /** 固定電話 */
    @SensitiveLengthFixedPhone
    String fixPhone;

    /** 地址 */
    @SensitiveLengthAddress
    String address;

    /** 身份證號 */
    @SensitiveLengthIdCard
    String idCard;

    /** 銀行卡號 */
    @SensitiveLengthBankCard
    String bankCard;

    /** 郵箱 */
    @SensitiveLengthEmail
    String email;

    /** 密碼 */
    @SensitiveLengthPassword
    String password;
}

基於日誌框架脫敏

在Logback框架中,可以通過自定義MessageConverter的方式實現對日誌消息脫敏處理。
具體實現可以參考sensitive-plus日誌脫敏

這種基於日誌框架的脫敏方式,有一些侷限性:

  1. 只能應用在日誌脫敏場景
  2. 基於正則式處理,對日誌格式有要求
  3. 存在性能瓶頸

請謹慎使用!

寫在最後

綜上,不論是日誌打印還是接口返回數據場景的脫敏需求,出於靈活性和性能考慮,都應該優先考慮在應用層處理。
至於在應用層處理的侵入性,可以通過項目約定進行統一即可。

【參考】
數據脫敏的 3 種常見方案,好用到爆!
logback-defender實現日誌脫敏
使用Logback脫敏-擴展篇
基於logback的日誌“規範”和“脫敏”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章