1. 什么是數據脫敏
1.1 數據脫敏的定義
數據脫敏百度百科中是這樣定義的: 數據脫敏,指對某些敏感信息通過脫敏規則進行數據的變形,實現敏感隱私數據的可靠保護。
這樣就可以在開發、測試和其它非生產環境以及外包環境中安全地使用脫敏后的真實數據集。在涉及客戶安全數據或者一些商業性敏感數據的情況下,在不違反系統規則條件下,對真實數據進行改造并提供測試使用,如身份證號、手機號、卡號、客戶號等個人信息都需要進行數據脫敏。是數據庫安全技術之一。
總的來說,數據脫敏是指對某些敏感信息通過脫敏規則進行數據的變形,實現敏感隱私數據的可靠保護。
在數據脫敏過程中,通常會采用不同的算法和技術,以根據不同的需求和場景對數據進行處理。
例如,對于身份證號碼,可以使用掩碼算法(masking)將前幾位數字保留,其他位用 “X” 或 "*" 代替;對于姓名,可以使用偽造(pseudonymization)算法,將真實姓名替換成隨機生成的假名。
1.2 常用脫敏規則
替換、重排、加密、截斷、掩碼
2. Hutool 工具介紹
2.1 引入 Maven 配置
在項目的 pom.xml 的 dependencies 中加入以下內容,這里以 5.8.16 版本為例。

注意:Hutool 5.x 支持 JDK8+, 如果你的項目使用 JDK7,請使用 Hutool 4.x 版本。本文使用的數據脫敏工具類只有在 5.6 + 版本以上才提供。
2.2 Hutool 包含的組件
一個 Java 基礎工具類,對文件、流、加密解密、轉碼、正則、線程、XML 等 JDK 方法進行封裝,組成各種 Util 工具類,同時提供以下組件:
| 模塊 | 介紹 |
|---|---|
| hutool-aop | JDK 動態代理封裝,提供非 IOC 下的切面支持 |
| hutool-bloomFilter | 布隆過濾,提供一些 Hash 算法的布隆過濾 |
| hutool-cache | 簡單緩存實現 |
| hutool-core | 核心,包括 Bean 操作、日期、各種 Util 等 |
| hutool-cron | 定時任務模塊,提供類 Crontab 表達式的定時任務 |
| hutool-crypto | 加密解密模塊,提供對稱、非對稱和摘要算法封裝 |
| hutool-db | JDBC 封裝后的數據操作,基于 ActiveRecord 思想 |
| hutool-dfa | 基于 DFA 模型的多關鍵字查找 |
| hutool-extra | 擴展模塊,對第三方封裝(模板引擎、郵件、Servlet、二維碼、Emoji、FTP、分詞等) |
| hutool-http | 基于 HttpUrlConnection 的 Http 客戶端封裝 |
| hutool-log | 自動識別日志實現的日志門面 |
| hutool-script | 腳本執行封裝,例如 Javascript |
| hutool-setting | 功能更強大的 Setting 配置文件和 Properties 封裝 |
| hutool-system | 系統參數調用封裝(JVM 信息等) |
| hutool-json | JSON 實現 |
| hutool-captcha | 圖片驗證碼實現 |
| hutool-poi | 針對 POI 中 Excel 和 Word 的封裝 |
| hutool-socket | 基于 Java 的 NIO 和 AIO 的 Socket 封裝 |
| hutool-jwt | JSON Web Token (JWT) 封裝實現 |
可以根據需求對每個模塊單獨引入,也可以通過引入hutool-all方式引入所有模塊,本文所使用的數據脫敏工具就是在 hutool.core 模塊。
2.3 Hutool 支持的脫敏數據類型
現階段最新版本的 Hutool 支持的脫敏數據類型如下,基本覆蓋了常見的敏感信息。
1.用戶 id
2.中文姓名
3.身份證號
4.座機號
5.手機號
6.地址
7.電子郵件
8.密碼
9.中國大陸車牌,包含普通車輛、新能源車輛
10.銀行卡
3. Hutool 數據脫敏實操
3.1 使用 Hutool 工具類一行代碼實現脫敏
Hutool 提供的脫敏方法如下圖所示:
??
注意:Hutool 脫敏是通過 * 來代替敏感信息的,具體實現是在 StrUtil.hide 方法中,如果我們想要自定義隱藏符號,則可以把 Hutool 的源碼拷出來,重新實現即可。 這里以手機號、銀行卡號、身份證號、密碼信息的脫敏為例,下面是對應的測試代碼。
importcn.hutool.core.util.DesensitizedUtil;
importorg.junit.Test;
importorg.springframework.boot.test.context.SpringBootTest;
/**
*
* @description: Hutool實現數據脫敏
*/
@SpringBootTest
publicclassHuToolDesensitizationTest{
@Test
publicvoidtestPhoneDesensitization(){
String phone="13723231234";
System.out.println(DesensitizedUtil.mobilePhone(phone));//輸出:137****1234
}
@Test
publicvoidtestBankCardDesensitization(){
String bankCard="6217000130008255666";
System.out.println(DesensitizedUtil.bankCard(bankCard));//輸出:6217 **** **** *** 5666
}
@Test
publicvoidtestIdCardNumDesensitization(){
String idCardNum="411021199901102321";
//只顯示前4位和后2位
System.out.println(DesensitizedUtil.idCardNum(idCardNum,4,2));//輸出:4110************21
}
@Test
publicvoidtestPasswordDesensitization(){
String password="www.jd.com_35711";
System.out.println(DesensitizedUtil.password(password));//輸出:****************
}
}
以上就是使用 Hutool 封裝好的工具類實現數據脫敏。
3.2 配合 JackSon 通過注解方式實現脫敏
現在有了數據脫敏工具類,如果前端需要顯示數據數據的地方比較多,我們不可能在每個地方都調用一個工具類,這樣就顯得代碼太冗余了,那我們如何通過注解的方式優雅的完成數據脫敏呢? 如果項目是基于 springboot 的 web 項目,則可以利用 springboot 自帶的 jackson 自定義序列化實現。它的實現原來其實就是在 json 進行序列化渲染給前端時,進行脫敏。
第一步:脫敏策略的枚舉。
/**
* @author
* @description:脫敏策略枚舉
*/
publicenumDesensitizationTypeEnum{
//自定義
MY_RULE,
//用戶id
USER_ID,
//中文名
CHINESE_NAME,
//身份證號
ID_CARD,
//座機號
FIXED_PHONE,
//手機號
MOBILE_PHONE,
//地址
ADDRESS,
//電子郵件
EMAIL,
//密碼
PASSWORD,
//中國大陸車牌,包含普通車輛、新能源車輛
CAR_LICENSE,
//銀行卡
BANK_CARD
}
上面表示支持的脫敏類型。第二步:定義一個用于脫敏的 Desensitization 注解。
@Retention (RetentionPolicy.RUNTIME):運行時生效。
@Target (ElementType.FIELD):可用在字段上。
@JacksonAnnotationsInside:此注解可以點進去看一下是一個元注解,主要是用戶打包其他注解一起使用。
@JsonSerialize:上面說到過,該注解的作用就是可自定義序列化,可以用在注解上,方法上,字段上,類上,運行時生效等等,根據提供的序列化類里面的重寫方法實現自定義序列化。
/**
* @author
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using =DesensitizationSerialize.class)
public@interface Desensitization{
/**
* 脫敏數據類型,在MY_RULE的時候,startInclude和endExclude生效
*/
DesensitizationTypeEnumtype()defaultDesensitizationTypeEnum.MY_RULE;
/**
* 脫敏開始位置(包含)
*/
intstartInclude()default0;
/**
* 脫敏結束位置(不包含)
*/
intendExclude()default0;
}
注:只有使用了自定義的脫敏枚舉 MY_RULE 的時候,開始位置和結束位置才生效。第三步:創建自定的序列化類 這一步是我們實現數據脫敏的關鍵。自定義序列化類繼承 JsonSerializer,實現 ContextualSerializer 接口,并重寫兩個方法。
/** * @author * @description: 自定義序列化類 */ @AllArgsConstructor @NoArgsConstructor publicclassDesensitizationSerializeextendsJsonSerializer經過上述三步,已經完成了通過注解實現數據脫敏了,下面我們來測試一下。 首先定義一個要測試的 pojo,對應的字段加入要脫敏的策略。implementsContextualSerializer{ privateDesensitizationTypeEnum type; privateInteger startInclude; privateInteger endExclude; @Override publicvoidserialize(String str,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)throwsIOException{ switch(type){ // 自定義類型脫敏 case MY_RULE: jsonGenerator.writeString(CharSequenceUtil.hide(str, startInclude, endExclude)); break; // userId脫敏 case USER_ID: jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId())); break; // 中文姓名脫敏 case CHINESE_NAME: jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str))); break; // 身份證脫敏 case ID_CARD: jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str),1,2)); break; // 固定電話脫敏 case FIXED_PHONE: jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str))); break; // 手機號脫敏 case MOBILE_PHONE: jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str))); break; // 地址脫敏 case ADDRESS: jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str),8)); break; // 郵箱脫敏 case EMAIL: jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str))); break; // 密碼脫敏 case PASSWORD: jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str))); break; // 中國車牌脫敏 case CAR_LICENSE: jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str))); break; // 銀行卡脫敏 case BANK_CARD: jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str))); break; default: } } @Override publicJsonSerializer> createContextual(SerializerProvider serializerProvider,BeanProperty beanProperty)throwsJsonMappingException{ if(beanProperty !=null){ // 判斷數據類型是否為String類型 if(Objects.equals(beanProperty.getType().getRawClass(),String.class)){ // 獲取定義的注解 Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class); // 為null if(desensitization ==null){ desensitization = beanProperty.getContextAnnotation(Desensitization.class); } // 不為null if(desensitization !=null){ // 創建定義的序列化類的實例并且返回,入參為注解定義的type,開始位置,結束位置。 returnnewDesensitizationSerialize(desensitization.type(), desensitization.startInclude(), desensitization.endExclude()); } } return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty); } return serializerProvider.findNullValueSerializer(null); } }
/**
*
* @description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
publicclassTestPojo{
privateString userName;
@Desensitization(type =DesensitizationTypeEnum.MOBILE_PHONE)
privateString phone;
@Desensitization(type =DesensitizationTypeEnum.PASSWORD)
privateString password;
@Desensitization(type =DesensitizationTypeEnum.MY_RULE, startInclude =0, endExclude =2)
privateString address;
}
接下來寫一個測試的 controller
@RestController
publicclassTestController{
@RequestMapping("/test")
publicTestPojotestDesensitization(){
TestPojo testPojo =newTestPojo();
testPojo.setUserName("我是用戶名");
testPojo.setAddress("地球中國-北京市通州區京東總部2號樓");
testPojo.setPhone("13782946666");
testPojo.setPassword("sunyangwei123123123.");
System.out.println(testPojo);
return testPojo;
}
}
??可以看到我們成功實現了數據脫敏。
4. 其他常見的數據脫敏工具推薦
除了本文介紹的 Hutool 工具之外,還有一些其他的數據脫敏工具,常見脫敏方法或工具如下所示:
4.1 Apache ShardingSphere
Apache ShardingSphere 下面存在一個數據脫敏模塊,此模塊集成的常用的數據脫敏的功能。其基本原理是對用戶輸入的 SQL 進行解析攔截,并依靠用戶的脫敏配置進行 SQL 的改寫,從而實現對原文字段的加密及加密字段的解密。最終實現對用戶無感的加解密存儲、查詢。
4.2 FastJSON
平時開發 Web 項目的時候,除了默認的 Spring 自帶的序列化工具,FastJson 也是一個很常用的 Spring web Restful 接口序列化的工具。 FastJSON 實現數據脫敏的方式主要有兩種:
基于注解 @JSONField 實現:需要自定義一個用于脫敏的序列化的類,然后在需要脫敏的字段上通過 @JSONField 中的 serializeUsing 指定為我們自定義的序列化類型即可。
基于序列化過濾器:需要實現 ValueFilter 接口,重寫 process 方法完成自定義脫敏,然后在 JSON 轉換時使用自定義的轉換策略。具體實現可參考這篇文章:https://juejin.cn/post/7067916686141161479
4.3 Mybatis-mate
mybatisplus 也提供了數據脫敏模塊,mybatis-mate,不過在使用之前需要配置授權碼。 配置內容如下所示:
# Mybatis Mate 配置
mybatis-mate:
cert:
grant: jxftsdfggggx
license: GKXP9r4MCJhGID/DTGigcBcLmZjb1YZGjE4GXaAoxbtGsPC20sxpEtiUr2F7Nb1ANTUekvF6Syo6DzraA4M4oacwoLVTglzfvaEfadfsd232485eLJK1QsskrSJmreMnEaNh9lsV7Lpbxy9JeGCeM0HPEbRvq8Y+8dUt5bQYLklsa3ZIBexir+4XykZY15uqn1pYIp4pEK0+aINTa57xjJNoWuBIqm7BdFIb4l1TAcPYMTsMXhF5hfMmKD2h391HxWTshJ6jbt4YqdKD167AgeoM+B+DE1jxlLjcpskY+kFs9piOS7RCcmKBBUOgX2BD/JxhR2gQ==
5. 總結
本文主要介紹了數據脫敏的相關內容,首先介紹了數據脫敏的概念,在此基礎上介紹了常用的數據脫敏規則;隨后介紹了本文的重點 Hutool 工具及其使用方法,在此基礎上進行了實操,分別演示了使用 DesensitizedUtil 工具類、配合 Jackson 通過注解的方式完成數據脫敏.
審核編輯:劉清
-
SQL
+關注
關注
1文章
806瀏覽量
46836 -
FTP
+關注
關注
0文章
118瀏覽量
42280 -
JVM
+關注
關注
0文章
161瀏覽量
13071 -
過濾器
+關注
關注
1文章
444瀏覽量
21005 -
JSON
+關注
關注
0文章
129瀏覽量
7797
原文標題:Hutool:一行代碼搞定數據脫敏
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
數據脫敏具體指的是什么?又是如何進行數據脫敏
SpringBoot日志脫敏的方式介紹
SpringBoot采用JsonSerializer和Aop實現可控制的數據脫敏
盤點一下PostgreSQL的幾種常用脫敏方式
SNP干貨分享:SAP數據脫敏的具體實施步驟
什么是數據脫敏?常用的脫敏規則有哪些呢?
評論