Go實(shí)現(xiàn)數(shù)據(jù)脫敏的方案設(shè)計(jì)
前言
在一些常見(jiàn)的業(yè)務(wù)場(chǎng)景中可能涉及到用戶的手機(jī)號(hào),銀行卡號(hào)等敏感數(shù)據(jù),對(duì)于這部分的數(shù)據(jù)經(jīng)常需要進(jìn)行數(shù)據(jù)脫敏處理,就是將此部分?jǐn)?shù)據(jù)隱私化,防止數(shù)據(jù)泄露。但是在生產(chǎn)環(huán)境中,數(shù)據(jù)一般都是實(shí)時(shí)的,且在進(jìn)行脫敏操作時(shí)不能影響正常的業(yè)務(wù)使用。
脫敏方案
脫敏方案一般會(huì)采用以下方式:
- 數(shù)據(jù)部分脫敏:只對(duì)部分內(nèi)容脫敏,保留一些關(guān)鍵部分,比如人名保留姓氏,其他使用星號(hào)或者其他占位符代替。
- 數(shù)據(jù)完全脫敏:對(duì)整個(gè)數(shù)據(jù)進(jìn)行脫敏,完全隱藏所有數(shù)據(jù),比如整個(gè)數(shù)據(jù)都是用占位符代替或者是用其他隨機(jī)生成的數(shù)據(jù)替換。
- 數(shù)據(jù)加密:直接對(duì)數(shù)據(jù)進(jìn)行加密,其實(shí)就是完全脫敏。加密方式更多用在數(shù)據(jù)傳輸或存儲(chǔ)的過(guò)程中。比如接口傳輸時(shí)加密某字段數(shù)據(jù)防止請(qǐng)求被攔截時(shí)數(shù)據(jù)泄露。
- 數(shù)據(jù)刪除,對(duì)于一些沒(méi)有必要且不再使用的數(shù)據(jù)應(yīng)當(dāng)直接刪除。
詳細(xì)設(shè)計(jì)
基本脫敏方法
就目前我所使用的場(chǎng)景,遇到比較多的是將在展示時(shí)對(duì)數(shù)據(jù)進(jìn)行部分脫敏后再展示,使用占位符替換。
// 部分?jǐn)?shù)據(jù)脫敏 func PlaceholderHandle(data string) string { if len(data) <= 4 { return strings.Repeat("*", len(data)) } return data[:3] + strings.Repeat("*", len(data)-7) + data[len(data)-4:] } // 完全數(shù)據(jù)脫敏 func PlaceFullHandle(){ return strings.Repeat("*", len(data)) } // 使用MD5對(duì)數(shù)據(jù)進(jìn)行加密 func GetMD5Hash(data string) string { hash := md5.Sum([]byte(text)) return hex.EncodeToString(hash[:]) } // 使用AES算法對(duì)數(shù)據(jù)進(jìn)行加密 func Encrypt(data []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } ciphertext := make([]byte, aes.BlockSize+len(data)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return nil, err } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[aes.BlockSize:], data) return ciphertext, nil } // 使用AES算法對(duì)數(shù)據(jù)進(jìn)行解密 func Decrypt(data []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } if len(data) < aes.BlockSize { return nil, fmt.Errorf("ciphertext too short") } iv := data[:aes.BlockSize] data = data[aes.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(data, data) return data, nil }
md5 是不可逆的,所以如果使用MD5 加密的話就數(shù)據(jù)就無(wú)法解密,如果使用MD5加密的話更適合的場(chǎng)景就是用于數(shù)據(jù)加密后沒(méi)有其他用處。所以如果希望加密后再解密可以使用AES 對(duì)稱加密算法進(jìn)行加解密,其還支持使用Key 進(jìn)行加密。
脫敏模塊
場(chǎng)景
- 項(xiàng)目中很多個(gè)模塊都需要進(jìn)行數(shù)據(jù)脫敏
- 數(shù)據(jù)脫敏的規(guī)則復(fù)雜,不同數(shù)據(jù)類(lèi)型,不同場(chǎng)景,不同角色有不同的脫敏規(guī)則
- 脫敏規(guī)則多變時(shí)需要有個(gè)統(tǒng)一管理中心,可以增加其靈活性,特別遇到動(dòng)態(tài)更新的需求時(shí)可以增加可配置功能
功能模塊劃分:
當(dāng)遇到以上點(diǎn)可以考慮設(shè)計(jì)一個(gè)專門(mén)進(jìn)行數(shù)據(jù)脫敏的模塊,以便統(tǒng)一管理和調(diào)度數(shù)據(jù)脫敏邏輯從而保證數(shù)據(jù)脫敏的一致性和規(guī)范性。一個(gè)簡(jiǎn)單的數(shù)據(jù)脫敏模塊大致劃分三個(gè)模塊:
- 數(shù)據(jù)源:獲取數(shù)據(jù)源,來(lái)源支持文件,數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源
- 解析器:解析數(shù)據(jù)源并對(duì)提取需要脫敏的字段
- 脫敏策略引擎:根據(jù)不同的規(guī)則對(duì)數(shù)據(jù)進(jìn)行脫敏處理
數(shù)據(jù)源可以使用 工廠函數(shù),根據(jù)數(shù)據(jù)源類(lèi)型創(chuàng)建對(duì)應(yīng)數(shù)據(jù)源實(shí)例從而調(diào)用方法 GetData 獲取相應(yīng)的數(shù)據(jù)源,后續(xù)可以增加其他數(shù)據(jù)源時(shí)只需要再工廠函數(shù)增加類(lèi)型和對(duì)應(yīng)的實(shí)例創(chuàng)建。
type DataSource interface { GetData() []byte } type UserDbSource struct { } func (p *UserDbSource) GetData() []byte { return nil } type OrderDbSource struct { dbName string } func (p *OrderDbSource) GetData() []byte { return nil } type ThirdpartySource struct { url string } func (p *ThirdpartySource) GetData() []byte { return nil } type DataSourceFactory struct { } func (p *DataSourceFactory) CreateDataSource(sourceType string, sourceConfig string) DataSource { switch sourceType { case "file": return &FileSource{filePath: sourceConfig} case "thirdparty": return &ThirdpartySource{url: sourceConfig} case "orderDb": return &OrderDbSource{dbName: sourceConfig} case "userDb": return &UserDbSource{} } return nil }
數(shù)據(jù)脫敏引擎使用策略模式,先定義不同的脫敏規(guī)則,并通過(guò)DataMaskCore接口統(tǒng)一了脫敏方法。在初始化DataMask結(jié)構(gòu)體可以根據(jù)傳入不同脫敏策略,然后在進(jìn)行脫敏處理時(shí)根據(jù)不同的脫敏規(guī)則進(jìn)行處理。這樣可以實(shí)現(xiàn)根據(jù)不同規(guī)則進(jìn)行不同的脫敏處理,使代碼更加靈活和可擴(kuò)展。
type DataMaskCore interface { DoMask(data string) } // 脫敏規(guī)則1 type MaskingRule1 struct{} func (mr1 *MaskingRule1) DoMask(data string) string { // 實(shí)現(xiàn)脫敏規(guī)則1的邏輯 return "Masked Data 1" } // 脫敏規(guī)則2 type MaskingRule2 struct{} func (mr2 MaskingRule2) DoMask(data string) string { // 實(shí)現(xiàn)脫敏規(guī)則2的邏輯 return "Masked Data 2" } type DataMask struct { Strategy DataMaskCore } func NewDataMask(strategy DataMaskCore) *DataMask { return &DataMask{ Strategy: strategy, } } // 根據(jù)不同規(guī)則進(jìn)行不同的脫敏處理 func (p *DataMask) MaskData(data string) { p.Strategy.DoMask(data) }
簡(jiǎn)單概述,數(shù)據(jù)脫敏其實(shí)本質(zhì)就是對(duì)數(shù)據(jù)不可直接展示。根據(jù)自身需求對(duì)數(shù)據(jù)敏感度,可使用簡(jiǎn)單處理方式就是對(duì)數(shù)據(jù)進(jìn)行占位符代替,或者直接加密處理。如果是沒(méi)有用處的數(shù)據(jù)直接暴力解決—刪除。
以上就是Go實(shí)現(xiàn)數(shù)據(jù)脫敏的方案設(shè)計(jì)的詳細(xì)內(nèi)容,更多關(guān)于Go數(shù)據(jù)脫敏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang中interface轉(zhuǎn)string輸出打印方法
這篇文章主要給大家介紹了關(guān)于Golang中interface轉(zhuǎn)string輸出打印的相關(guān)資料,在go語(yǔ)言中interface轉(zhuǎn)string可以直接使用fmt提供的fmt函數(shù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02Go項(xiàng)目實(shí)現(xiàn)優(yōu)雅關(guān)機(jī)與平滑重啟功能
無(wú)論是優(yōu)雅關(guān)機(jī)還是優(yōu)雅重啟歸根結(jié)底都是通過(guò)監(jiān)聽(tīng)特定系統(tǒng)信號(hào),然后執(zhí)行一定的邏輯處理保障當(dāng)前系統(tǒng)正在處理的請(qǐng)求被正常處理后再關(guān)閉當(dāng)前進(jìn)程,這篇文章主要介紹了Go實(shí)現(xiàn)優(yōu)雅關(guān)機(jī)與平滑重啟 ,需要的朋友可以參考下2022-10-10go local history本地歷史恢復(fù)代碼神器
這篇文章主要為大家介紹了go local history本地歷史恢復(fù)代碼神器的使用功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01使用Go重構(gòu)流式日志網(wǎng)關(guān)的實(shí)戰(zhàn)分享
流式日志網(wǎng)關(guān)的主要功能是提供?HTTP?接口,接收?CDN?邊緣節(jié)點(diǎn)上報(bào)的各類(lèi)日志(訪問(wèn)日志/報(bào)錯(cuò)日志/計(jì)費(fèi)日志等),將日志作預(yù)處理并分流到多個(gè)的?Kafka?集群和?Topic?中,本文就給大家分享如何使用?Go?重構(gòu)流式日志網(wǎng)關(guān)2023-06-06golang文件服務(wù)器的兩種方式(可以訪問(wèn)任何目錄)
這篇文章主要介紹了golang文件服務(wù)器的兩種方式,可以訪問(wèn)任何目錄,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Go語(yǔ)言共享內(nèi)存讀寫(xiě)實(shí)例分析
這篇文章主要介紹了Go語(yǔ)言共享內(nèi)存讀寫(xiě)方法,實(shí)例分析了共享內(nèi)存的原理與讀寫(xiě)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02