什么是數(shù)據(jù)脫敏
開胃菜
使用 Hutool 工具類實現(xiàn)數(shù)據(jù)掩碼
使用 Jackson 進行數(shù)據(jù)序列化脫敏
注解實現(xiàn)數(shù)據(jù)脫敏
1、定義一個注解
2、創(chuàng)建一個枚舉類
3、創(chuàng)建我們的自定義序列化類
4、測試
后記
本文主要分享什么是數(shù)據(jù)脫敏,如何優(yōu)雅的在項目中運用一個注解實現(xiàn)數(shù)據(jù)脫敏,為項目進行賦能。希望能給你們帶來幫助。
什么是數(shù)據(jù)脫敏
數(shù)據(jù)脫敏是一種通過去除或替換敏感數(shù)據(jù)中的部分信息,以保護數(shù)據(jù)隱私和安全的技術。其主要目的是確保數(shù)據(jù)仍然可以在各種場景中使用,同時保護敏感信息,防止數(shù)據(jù)泄露和濫用。數(shù)據(jù)脫敏通常用于處理包含個人身份信息和其他敏感信息的數(shù)據(jù)集,如手機號、姓名、地址、銀行卡、身份證號、車牌號等等。
在數(shù)據(jù)脫敏過程中,通常會采用不同的算法和技術,以根據(jù)不同的需求和場景對數(shù)據(jù)進行處理。例如,對于身份證號碼,可以使用掩碼算法(masking)將前幾位數(shù)字保留,其他位用“X”或"*"代替;對于姓名,可以使用偽造(pseudonymization)算法,將真實姓名替換成隨機生成的假名。
下面我講為大家?guī)頂?shù)據(jù)脫敏掩碼操作,讓我們一起學起來吧。
基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能
項目地址:https://github.com/YunaiV/ruoyi-vue-pro
視頻教程:https://doc.iocoder.cn/video/
開胃菜
下面給大家介紹的是使用兩種不同的工具類進行數(shù)據(jù)脫敏,而我們今天的主題使用一個注解解決數(shù)據(jù)脫敏問題的主要兩個工具類。來跟著我學習吧。
使用 Hutool 工具類實現(xiàn)數(shù)據(jù)掩碼
比喻說我們現(xiàn)在要對手機號進行數(shù)據(jù)脫敏,前三后四不掩碼,其他全部用 * 進行掩碼
如下圖代碼所示,
我們定義了一個手機號:17677772345,需要進行數(shù)據(jù)脫敏。
調用的 Hutool 的信息脫敏工具類。
我們運行一下看看結果。一個簡單的數(shù)據(jù)脫敏就實現(xiàn)了。
Hutool 信息脫敏工具類
根據(jù)上面的一個 Demo,大家可以看到我使用了 Hutool 的信息脫敏工具類進行對手機號掩碼脫敏。那么讓我們一起看看 Hutool 信息脫敏的工具類吧。
官網文檔:
https://hutool.cn/docs/#/core/工具類/信息脫敏工具-DesensitizedUtil
看一下官網的介紹,支持多種脫敏數(shù)據(jù)類型,滿足我們大部分需求,如果需要自定義還提供了自定義的方法實現(xiàn)。
下面是里面定義號的脫敏規(guī)則,直接調用就可以實現(xiàn)簡單的數(shù)據(jù)脫敏,這里給大家介紹是因為我們今天要給大家?guī)淼淖⒔鈱崿F(xiàn)數(shù)據(jù)脫敏核心就是利用我們的 Hutool 提供的工具類實現(xiàn),支持自定義隱藏。
使用 Jackson 進行數(shù)據(jù)序列化脫敏
首先創(chuàng)建一個實體類,此實體類只有一個測試的手機號。
注解的講解:
@Data:lombok 的注解生成 get,set 等等方法。
@JsonSerialize(using = TestJacksonSerialize.class):該注解的作用就是可自定義序列化,可以用在注解上,方法上,字段上,類上,運行時生效等等,根據(jù)提供的序列化類里面的重寫方法實現(xiàn)自定義序列化。可以看下下面的源碼,有興趣的朋友可以去了解一下,也能解決我們日常開發(fā)中很多場景。
@Data publicclassTestDTOimplementsSerializable{ /** *手機號 */ @JsonSerialize(using=TestJacksonSerialize.class) privateStringphone; }
然后創(chuàng)建一個 TestJacksonSerialize 類實現(xiàn)自定義序列化。
此類主要繼承 JsonSerializer,因為我們這里需要序列化的類型是 String 泛型就選擇 String。注意如果你使用此注解作用在類上的話,這里就是你要序列化的類。
重寫序列化方法,里面的實現(xiàn)很簡單就是調用我們的 Hutool 工具類進行手機號數(shù)據(jù)脫敏。
publicclassTestJacksonSerializeextendsJsonSerializer{ @Override @SneakyThrows publicvoidserialize(Stringstr,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider){ //使用我們的hutool工具類進行手機號脫敏 jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str))); } }
讓我們測試一下吧,因為此注解是運行時生效,我們定義一個接口來測試。
@RestController @RequestMapping("/test") publicclassTestApi{ @GetMapping publicTestDTOtest(){ TestDTOtestDTO=newTestDTO(); testDTO.setPhone("17677772345"); returntestDTO; } }
可以看到測試成功,經過上面的兩個工具類的介紹,聯(lián)想一下我們怎么通過兩個工具類定義一個自己的注解實現(xiàn)數(shù)據(jù)脫敏呢。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能
項目地址:https://github.com/YunaiV/yudao-cloud
視頻教程:https://doc.iocoder.cn/video/
注解實現(xiàn)數(shù)據(jù)脫敏
我們考慮一下,工具類現(xiàn)在有了,那么我們怎么去實現(xiàn)一個注解優(yōu)雅的解決數(shù)據(jù)脫敏呢?
請看下文,讓我?guī)Т蠹乙黄饘W習。
1、定義一個注解
定義一個 Desensitization 注解。
@Retention(RetentionPolicy.RUNTIME):運行時生效。
@Target(ElementType.FIELD):可用在字段上。
@JacksonAnnotationsInside:此注解可以點進去看一下是一個元注解,主要是用戶打包其他注解一起使用。
@JsonSerialize:上面說到過,該注解的作用就是可自定義序列化,可以用在注解上,方法上,字段上,類上,運行時生效等等,根據(jù)提供的序列化類里面的重寫方法實現(xiàn)自定義序列化。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using=DesensitizationSerialize.class) public@interfaceDesensitization{ /** *脫敏數(shù)據(jù)類型,只要在CUSTOMER的時候,startInclude和endExclude生效 */ DesensitizationTypeEnumtype()defaultDesensitizationTypeEnum.CUSTOMER; /** *開始位置(包含) */ intstartInclude()default0; /** *結束位置(不包含) */ intendExclude()default0; }
可以看到此注解有三個值,一個是枚舉類定義了我們的脫敏數(shù)據(jù)類型。一個開始位置,一個結束位置。
枚舉類待會給大家講解,如果選擇了自定義類型,下面的開始位置,結束位置才生效。
開始結束位置是我們 Hutool 工具提供的自定義脫敏實現(xiàn)需要的參數(shù)??梢钥创朔椒?,需要提出一點的是此方法硬編碼了掩碼值。如果我們的場景需要其他掩碼值的話實現(xiàn)也很簡單,把 Hutool 的源碼拷出來,代替他的硬編碼,就可以實現(xiàn)。
2、創(chuàng)建一個枚舉類
此枚舉類是我們數(shù)據(jù)脫敏的類型,包括了大部分場景。以及可以滿足我們日常開發(fā)咯。
publicenumDesensitizationTypeEnum{ //自定義 CUSTOMER, //用戶id USER_ID, //中文名 CHINESE_NAME, //身份證號 ID_CARD, //座機號 FIXED_PHONE, //手機號 MOBILE_PHONE, //地址 ADDRESS, //電子郵件 EMAIL, //密碼 PASSWORD, //中國大陸車牌,包含普通車輛、新能源車輛 CAR_LICENSE, //銀行卡 BANK_CARD }
3、創(chuàng)建我們的自定義序列化類
此類是我們數(shù)據(jù)脫敏的關鍵。主要是繼承了我們的 JsonSerializer,實現(xiàn)了我的ContextualSerializer。重寫了它倆的方法。
@NoArgsConstructor:Lombok 無參構造生成。
@AllArgsConstructor:Lombok 有參生成。
ContextualSerializer:這個類是序列化上下文類,主要是解決我們這個地方獲取字段的一些信息,可以看一下源碼,他的實現(xiàn)類有很多,Jackson 提供的 @JsonFormat 注解也是實現(xiàn)此類,獲取字段的一些信息進行序列化的。有興趣的朋友可以看一下,多看源碼,才能學到 Jackson 的實現(xiàn)方法,才能有今天我們的實現(xiàn)。
兩個重寫的方法解讀:
serialize:重寫,實現(xiàn)我們的序列化自定義。
createContextual:序列化上下文方法重寫,獲取我們的字段一些信息進行判斷,然后返回實例。具體代碼可以看下面代碼,都有注釋噢。
@NoArgsConstructor @AllArgsConstructor publicclassDesensitizationSerializeextendsJsonSerializerimplementsContextualSerializer{ privateDesensitizationTypeEnumtype; privateIntegerstartInclude; privateIntegerendExclude; @Override publicvoidserialize(Stringstr,JsonGeneratorjsonGenerator,SerializerProviderserializerProvider)throwsIOException{ switch(type){ //自定義類型脫敏 caseCUSTOMER: jsonGenerator.writeString(CharSequenceUtil.hide(str,startInclude,endExclude)); break; //userId脫敏 caseUSER_ID: jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId())); break; //中文姓名脫敏 caseCHINESE_NAME: jsonGenerator.writeString(DesensitizedUtil.chineseName(String.valueOf(str))); break; //身份證脫敏 caseID_CARD: jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str),1,2)); break; //固定電話脫敏 caseFIXED_PHONE: jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str))); break; //手機號脫敏 caseMOBILE_PHONE: jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str))); break; //地址脫敏 caseADDRESS: jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str),8)); break; //郵箱脫敏 caseEMAIL: jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str))); break; //密碼脫敏 casePASSWORD: jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str))); break; //中國車牌脫敏 caseCAR_LICENSE: jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str))); break; //銀行卡脫敏 caseBANK_CARD: jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str))); break; default: } } @Override publicJsonSerializer>createContextual(SerializerProviderserializerProvider,BeanPropertybeanProperty)throwsJsonMappingException{ if(beanProperty!=null){ //判斷數(shù)據(jù)類型是否為String類型 if(Objects.equals(beanProperty.getType().getRawClass(),String.class)){ //獲取定義的注解 Desensitizationdesensitization=beanProperty.getAnnotation(Desensitization.class); //為null if(desensitization==null){ desensitization=beanProperty.getContextAnnotation(Desensitization.class); } //不為null if(desensitization!=null){ //創(chuàng)建定義的序列化類的實例并且返回,入參為注解定義的type,開始位置,結束位置。 returnnewDesensitizationSerialize(desensitization.type(),desensitization.startInclude(), desensitization.endExclude()); } } returnserializerProvider.findValueSerializer(beanProperty.getType(),beanProperty); } returnserializerProvider.findNullValueSerializer(null); } }
4、測試
創(chuàng)建一個測試注解的 DTO,此測試如下。
@Data publicclassTestAnnotationDTOimplementsSerializable{ /** *自定義 */ @Desensitization(type=DesensitizationTypeEnum.CUSTOMER,startInclude=5,endExclude=10) privateStringcustom; /** *手機號 */ @Desensitization(type=DesensitizationTypeEnum.MOBILE_PHONE) privateStringphone; /** *郵箱 */ @Desensitization(type=DesensitizationTypeEnum.EMAIL) privateStringemail; /** *身份證 */ @Desensitization(type=DesensitizationTypeEnum.ID_CARD) privateStringidCard; }
新增測試接口:
@GetMapping("/test-annotation") publicTestAnnotationDTOtestAnnotation(){ TestAnnotationDTOtestAnnotationDTO=newTestAnnotationDTO(); testAnnotationDTO.setPhone("17677772345"); testAnnotationDTO.setCustom("111111111111111111"); testAnnotationDTO.setEmail("1433926101@qq.com"); testAnnotationDTO.setIdCard("4444199810015555"); returntestAnnotationDTO; }
測試一下看看效果。如下圖所示,完美!
項目 pom 文件
4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.10 com.jiaqing tool-desensitization 0.0.1-SNAPSHOT tool-desensitization 數(shù)據(jù)脫敏 1.8 5.8.5 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web cn.hutool hutool-core ${hutool.version} org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-json org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok
后記
今天給大家?guī)淼氖侨绾螌崿F(xiàn)一個注解進行數(shù)據(jù)脫敏。
責任編輯:彭菁
-
數(shù)據(jù)
+關注
關注
8文章
6808瀏覽量
88743 -
小程序
+關注
關注
1文章
234瀏覽量
12079
原文標題:太強了!一個注解解決數(shù)據(jù)脫敏問題
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論