1. 什么是數(shù)據(jù)脫敏
1.1 數(shù)據(jù)脫敏的定義
數(shù)據(jù)脫敏百度百科中是這樣定義的: 數(shù)據(jù)脫敏,指對某些敏感信息通過脫敏規(guī)則進(jìn)行數(shù)據(jù)的變形,實現(xiàn)敏感隱私數(shù)據(jù)的可靠保護。
這樣就可以在開發(fā)、測試和其它非生產(chǎn)環(huán)境以及外包環(huán)境中安全地使用脫敏后的真實數(shù)據(jù)集。在涉及客戶安全數(shù)據(jù)或者一些商業(yè)性敏感數(shù)據(jù)的情況下,在不違反系統(tǒng)規(guī)則條件下,對真實數(shù)據(jù)進(jìn)行改造并提供測試使用,如身份證號、手機號、卡號、客戶號等個人信息都需要進(jìn)行數(shù)據(jù)脫敏。是數(shù)據(jù)庫安全技術(shù)之一。
總的來說,數(shù)據(jù)脫敏是指對某些敏感信息通過脫敏規(guī)則進(jìn)行數(shù)據(jù)的變形,實現(xiàn)敏感隱私數(shù)據(jù)的可靠保護。
在數(shù)據(jù)脫敏過程中,通常會采用不同的算法和技術(shù),以根據(jù)不同的需求和場景對數(shù)據(jù)進(jìn)行處理。
例如,對于身份證號碼,可以使用掩碼算法(masking)將前幾位數(shù)字保留,其他位用 “X” 或 "*" 代替;對于姓名,可以使用偽造(pseudonymization)算法,將真實姓名替換成隨機生成的假名。
1.2 常用脫敏規(guī)則
替換、重排、加密、截斷、掩碼
2. Hutool 工具介紹
2.1 引入 Maven 配置
在項目的 pom.xml 的 dependencies 中加入以下內(nèi)容,這里以 5.8.16 版本為例。
注意:Hutool 5.x 支持 JDK8+, 如果你的項目使用 JDK7,請使用 Hutool 4.x 版本。本文使用的數(shù)據(jù)脫敏工具類只有在 5.6 + 版本以上才提供。
2.2 Hutool 包含的組件
一個 Java 基礎(chǔ)工具類,對文件、流、加密解密、轉(zhuǎn)碼、正則、線程、XML 等 JDK 方法進(jìn)行封裝,組成各種 Util 工具類,同時提供以下組件:
模塊 | 介紹 |
---|---|
hutool-aop | JDK 動態(tài)代理封裝,提供非 IOC 下的切面支持 |
hutool-bloomFilter | 布隆過濾,提供一些 Hash 算法的布隆過濾 |
hutool-cache | 簡單緩存實現(xiàn) |
hutool-core | 核心,包括 Bean 操作、日期、各種 Util 等 |
hutool-cron | 定時任務(wù)模塊,提供類 Crontab 表達(dá)式的定時任務(wù) |
hutool-crypto | 加密解密模塊,提供對稱、非對稱和摘要算法封裝 |
hutool-db | JDBC 封裝后的數(shù)據(jù)操作,基于 ActiveRecord 思想 |
hutool-dfa | 基于 DFA 模型的多關(guān)鍵字查找 |
hutool-extra | 擴展模塊,對第三方封裝(模板引擎、郵件、Servlet、二維碼、Emoji、FTP、分詞等) |
hutool-http | 基于 HttpUrlConnection 的 Http 客戶端封裝 |
hutool-log | 自動識別日志實現(xiàn)的日志門面 |
hutool-script | 腳本執(zhí)行封裝,例如 Javascript |
hutool-setting | 功能更強大的 Setting 配置文件和 Properties 封裝 |
hutool-system | 系統(tǒng)參數(shù)調(diào)用封裝(JVM 信息等) |
hutool-json | JSON 實現(xiàn) |
hutool-captcha | 圖片驗證碼實現(xiàn) |
hutool-poi | 針對 POI 中 Excel 和 Word 的封裝 |
hutool-socket | 基于 Java 的 NIO 和 AIO 的 Socket 封裝 |
hutool-jwt | JSON Web Token (JWT) 封裝實現(xiàn) |
可以根據(jù)需求對每個模塊單獨引入,也可以通過引入hutool-all方式引入所有模塊,本文所使用的數(shù)據(jù)脫敏工具就是在 hutool.core 模塊。
2.3 Hutool 支持的脫敏數(shù)據(jù)類型
現(xiàn)階段最新版本的 Hutool 支持的脫敏數(shù)據(jù)類型如下,基本覆蓋了常見的敏感信息。
1.用戶 id
2.中文姓名
3.身份證號
4.座機號
5.手機號
6.地址
7.電子郵件
8.密碼
9.中國大陸車牌,包含普通車輛、新能源車輛
10.銀行卡
3. Hutool 數(shù)據(jù)脫敏實操
3.1 使用 Hutool 工具類一行代碼實現(xiàn)脫敏
Hutool 提供的脫敏方法如下圖所示:
??
注意:Hutool 脫敏是通過 * 來代替敏感信息的,具體實現(xiàn)是在 StrUtil.hide 方法中,如果我們想要自定義隱藏符號,則可以把 Hutool 的源碼拷出來,重新實現(xiàn)即可。 這里以手機號、銀行卡號、身份證號、密碼信息的脫敏為例,下面是對應(yīng)的測試代碼。
importcn.hutool.core.util.DesensitizedUtil; importorg.junit.Test; importorg.springframework.boot.test.context.SpringBootTest; /** * * @description: Hutool實現(xiàn)數(shù)據(jù)脫敏 */ @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 封裝好的工具類實現(xiàn)數(shù)據(jù)脫敏。
3.2 配合 JackSon 通過注解方式實現(xiàn)脫敏
現(xiàn)在有了數(shù)據(jù)脫敏工具類,如果前端需要顯示數(shù)據(jù)數(shù)據(jù)的地方比較多,我們不可能在每個地方都調(diào)用一個工具類,這樣就顯得代碼太冗余了,那我們?nèi)绾瓮ㄟ^注解的方式優(yōu)雅的完成數(shù)據(jù)脫敏呢? 如果項目是基于 springboot 的 web 項目,則可以利用 springboot 自帶的 jackson 自定義序列化實現(xiàn)。它的實現(xiàn)原來其實就是在 json 進(jìn)行序列化渲染給前端時,進(jìn)行脫敏。
第一步:脫敏策略的枚舉。
/** * @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:此注解可以點進(jìn)去看一下是一個元注解,主要是用戶打包其他注解一起使用。
@JsonSerialize:上面說到過,該注解的作用就是可自定義序列化,可以用在注解上,方法上,字段上,類上,運行時生效等等,根據(jù)提供的序列化類里面的重寫方法實現(xiàn)自定義序列化。
/** * @author */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using =DesensitizationSerialize.class) public@interface Desensitization{ /** * 脫敏數(shù)據(jù)類型,在MY_RULE的時候,startInclude和endExclude生效 */ DesensitizationTypeEnumtype()defaultDesensitizationTypeEnum.MY_RULE; /** * 脫敏開始位置(包含) */ intstartInclude()default0; /** * 脫敏結(jié)束位置(不包含) */ intendExclude()default0; }注:只有使用了自定義的脫敏枚舉 MY_RULE 的時候,開始位置和結(jié)束位置才生效。
第三步:創(chuàng)建自定的序列化類 這一步是我們實現(xiàn)數(shù)據(jù)脫敏的關(guān)鍵。自定義序列化類繼承 JsonSerializer,實現(xiàn) ContextualSerializer 接口,并重寫兩個方法。
/** * @author * @description: 自定義序列化類 */ @AllArgsConstructor @NoArgsConstructor publicclassDesensitizationSerializeextendsJsonSerializer經(jīng)過上述三步,已經(jīng)完成了通過注解實現(xiàn)數(shù)據(jù)脫敏了,下面我們來測試一下。 首先定義一個要測試的 pojo,對應(yīng)的字段加入要脫敏的策略。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){ // 判斷數(shù)據(jù)類型是否為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){ // 創(chuàng)建定義的序列化類的實例并且返回,入?yún)樽⒔舛x的type,開始位置,結(jié)束位置。 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("地球中國-北京市通州區(qū)京東總部2號樓"); testPojo.setPhone("13782946666"); testPojo.setPassword("sunyangwei123123123."); System.out.println(testPojo); return testPojo; } }??
可以看到我們成功實現(xiàn)了數(shù)據(jù)脫敏。
4. 其他常見的數(shù)據(jù)脫敏工具推薦
除了本文介紹的 Hutool 工具之外,還有一些其他的數(shù)據(jù)脫敏工具,常見脫敏方法或工具如下所示:
4.1 Apache ShardingSphere
Apache ShardingSphere 下面存在一個數(shù)據(jù)脫敏模塊,此模塊集成的常用的數(shù)據(jù)脫敏的功能。其基本原理是對用戶輸入的 SQL 進(jìn)行解析攔截,并依靠用戶的脫敏配置進(jìn)行 SQL 的改寫,從而實現(xiàn)對原文字段的加密及加密字段的解密。最終實現(xiàn)對用戶無感的加解密存儲、查詢。
4.2 FastJSON
平時開發(fā) Web 項目的時候,除了默認(rèn)的 Spring 自帶的序列化工具,F(xiàn)astJson 也是一個很常用的 Spring web Restful 接口序列化的工具。 FastJSON 實現(xiàn)數(shù)據(jù)脫敏的方式主要有兩種:
基于注解 @JSONField 實現(xiàn):需要自定義一個用于脫敏的序列化的類,然后在需要脫敏的字段上通過 @JSONField 中的 serializeUsing 指定為我們自定義的序列化類型即可。
基于序列化過濾器:需要實現(xiàn) ValueFilter 接口,重寫 process 方法完成自定義脫敏,然后在 JSON 轉(zhuǎn)換時使用自定義的轉(zhuǎn)換策略。具體實現(xiàn)可參考這篇文章:https://juejin.cn/post/7067916686141161479
4.3 Mybatis-mate
mybatisplus 也提供了數(shù)據(jù)脫敏模塊,mybatis-mate,不過在使用之前需要配置授權(quán)碼。 配置內(nèi)容如下所示:
# Mybatis Mate 配置 mybatis-mate: cert: grant: jxftsdfggggx license: GKXP9r4MCJhGID/DTGigcBcLmZjb1YZGjE4GXaAoxbtGsPC20sxpEtiUr2F7Nb1ANTUekvF6Syo6DzraA4M4oacwoLVTglzfvaEfadfsd232485eLJK1QsskrSJmreMnEaNh9lsV7Lpbxy9JeGCeM0HPEbRvq8Y+8dUt5bQYLklsa3ZIBexir+4XykZY15uqn1pYIp4pEK0+aINTa57xjJNoWuBIqm7BdFIb4l1TAcPYMTsMXhF5hfMmKD2h391HxWTshJ6jbt4YqdKD167AgeoM+B+DE1jxlLjcpskY+kFs9piOS7RCcmKBBUOgX2BD/JxhR2gQ==
5. 總結(jié)
本文主要介紹了數(shù)據(jù)脫敏的相關(guān)內(nèi)容,首先介紹了數(shù)據(jù)脫敏的概念,在此基礎(chǔ)上介紹了常用的數(shù)據(jù)脫敏規(guī)則;隨后介紹了本文的重點 Hutool 工具及其使用方法,在此基礎(chǔ)上進(jìn)行了實操,分別演示了使用 DesensitizedUtil 工具類、配合 Jackson 通過注解的方式完成數(shù)據(jù)脫敏.
審核編輯:劉清
-
SQL
+關(guān)注
關(guān)注
1文章
762瀏覽量
44115 -
FTP
+關(guān)注
關(guān)注
0文章
110瀏覽量
40623 -
JVM
+關(guān)注
關(guān)注
0文章
158瀏覽量
12220 -
過濾器
+關(guān)注
關(guān)注
1文章
428瀏覽量
19593 -
JSON
+關(guān)注
關(guān)注
0文章
117瀏覽量
6963
原文標(biāo)題:Hutool:一行代碼搞定數(shù)據(jù)脫敏
文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論