潘娟,京東數科高級DBA,主要負責京東數科數據庫中間件開發、數據庫運維自動化平臺開發、生產數據庫運維工做。屢次參與京東6.1八、11.11等大促活動的護航工做。曾負責京東數科數據庫自動化平臺設計與開發項目,現專一於Apache ShardingSphere分佈式數據庫中間件開發。樂於在數據庫、自動化、分佈式、中間件等相關領域進行學習和探索。git
《ApacheShardingSphere數據脫敏全解決方案詳解(上)》主要介紹了ShardingSphere內部脫敏功能的具體實現。本次分享承接上篇,將具體實現與實際的場景結合,提供針對已上線業務脫敏改造和新上線業務脫敏使用的詳細介紹。github
在瞭解了ShardingSphere脫敏處理流程後,便可將脫敏配置、脫敏處理流程與實際場景進行結合。全部的設計開發都是爲了解決業務場景遇到的痛點。那麼面對以前提到的業務場景需求,又應該如何使用ShardingSphere這把利器來知足業務需求呢?數據庫
業務場景分析:新上線業務因爲一切從零開始,不存在歷史數據清洗問題,因此相對簡單。apache
解決方案說明:選擇合適的加密器,如AES後,只需配置邏輯列(面向用戶編寫SQL)和密文列(數據表存密文數據)便可,邏輯列和密文列能夠相同也能夠不一樣。建議配置以下(Yaml格式展現):編程
encryptRule:
encryptors:
aes_encryptor:
type: aes
props:
aes.key.value: 123456abc
tables:
t_user:
columns:
pwd:
cipherColumn: pwd
encryptor: aes_encryptor後端
使用這套配置,Encrypt-JDBC只需將logicColumn和cipherColumn進行轉換,底層數據表不存儲明文,只存儲了密文,這也是安全審計部分的要求所在。若是用戶但願將明文、密文一同存儲到數據庫,只需添加plainColumn配置便可。總體處理流程以下圖所示:安全
業務場景分析:因爲業務已經在線上運行,數據庫裏必然存有大量明文歷史數據。如今的問題是如何讓歷史數據得以加密清洗、如何讓增量數據得以加密處理、如何讓業務在新舊兩套數據系統之間進行無縫、透明化遷移。服務器
解決方案說明:在提供解決方案以前,咱們先來頭腦風暴一下:首先,既然是舊業務須要進行脫敏改造,那必定存儲了很是重要且敏感的信息。這些信息含金量高且業務相對基礎重要。若是搞錯了,整個團隊KPI就再見了。因此不可能一上來就停業務,禁止新數據寫入,再找個加密器把歷史數據所有加密清洗,再把以前重構的代碼部署上線,使其能把存量和增量數據進行在線加密解密。如此簡單粗暴的方式,按照歷史經驗來談,必定涼涼。運維
那麼另外一種相對安全的作法是:從新搭建一套和生產環境如出一轍的預發環境,而後經過相關遷移洗數工具把生產環境的存量原文數據加密後存儲到預發環境,而新增數據則經過例如MySQL主從複製及業務方自行開發的工具加密後存儲到預發環境的數據庫裏,再把重構後能夠進行加解密的代碼部署到預發環境。這樣生產環境是一套以明文爲核心的查詢修改的環境;預發環境是一套以密文爲核心加解密查詢修改的環境。在對比一段時間無誤後,能夠夜間操做將生產流量切到預發環境中。此方案相對安全可靠,只是時間、人力、資金、成本較高,主要包括:預發環境搭建、生產代碼整改、相關輔助工具開發等。除非無路可走,不然業務開發人員通常是從入門到放棄。分佈式
業務開發人員最但願的作法是:減小資金費用的承擔、最好不要修改業務代碼、可以安全平滑遷移系統。因而,ShardingSphere的脫敏功能模塊便應用而生。可分爲三步進行:
假設系統須要對t_user的pwd字段進行脫敏處理,業務方使用Encrypt-JDBC來代替標準化的JDBC接口,此舉基本不須要額外改造(咱們還提供了SpringBoot,SpringNameSpace,Yaml等接入方式,知足不一樣業務方需求)。另外,提供一套脫敏配置規則,以下所示:
encryptRule:
encryptors:
aes_encryptor:
type: aes
props:
aes.key.value: 123456abc
tables:
t_user:
columns:
pwd:
plainColumn: pwd
cipherColumn: pwd_cipher
encryptor: aes_encryptor
props:
query.with.cipher.column: false
依據上述脫敏規則可知,首先須要在數據庫表t_user裏新增一個字段叫作pwd_cipher,即cipherColumn,用於存放密文數據,同時咱們把plainColumn設置爲pwd,用於存放明文數據,而把logicColumn也設置爲pwd。因爲以前的代碼SQL就是使用pwd進行編寫,即面向邏輯列進行SQL編寫,因此業務代碼無需改動。經過Encrypt-JDBC,針對新增的數據,會把明文寫到pwd列,並同時把明文進行加密存儲到pwd_cipher列。此時,因爲query.with.cipher.column設置爲false,對業務應用來講,依舊使用pwd這一明文列進行查詢存儲,卻在底層數據庫表pwd_cipher上額外存儲了新增數據的密文數據,其處理流程以下圖所示:
新增數據在插入時,就經過Encrypt-JDBC加密爲密文數據,並被存儲到了cipherColumn。而如今就須要處理歷史明文存量數據。因爲Apache ShardingSphere目前並未提供相關遷移洗數工具,此時須要業務方自行將pwd中的明文數據進行加密處理存儲到pwd_cipher。
新增的數據已被Encrypt-JDBC將密文存儲到密文列,明文存儲到明文列;歷史數據被業務方自行加密清洗後,將密文也存儲到密文列。也就是說如今的數據庫裏即存放着明文也存放着密文,只是因爲配置項中的query.with.cipher.column=false,因此密文一直沒有被使用過。如今咱們爲了讓系統能切到密文數據進行查詢,須要將脫敏配置中的query.with.cipher.column設置爲true。在重啓系統後,咱們發現系統業務一切正常,可是Encrypt-JDBC已經開始從數據庫裏取出密文列的數據,解密後返回給用戶;而對於用戶的增刪改需求,則依舊會把原文數據存儲到明文列,加密後密文數據存儲到密文列。
雖然如今業務系統經過將密文列的數據取出,解密後返回;可是,在存儲的時候仍舊會存一份原文數據到明文列,這是爲何呢?答案是:爲了可以進行系統回滾。由於只要密文和明文永遠同時存在,咱們就能夠經過開關項配置自由將業務查詢切換到cipherColumn或plainColumn。也就是說,若是將系統切到密文列進行查詢時,發現系統報錯,須要回滾。那麼只需將query.with.cipher.column=false,Encrypt-JDBC將會還原,即又從新開始使用plainColumn進行查詢。處理流程以下圖所示:
因爲安全審計部門要求,業務系統通常不可能讓數據庫的明文列和密文列永久同步保留,咱們須要在系統穩定後將明文列數據刪除。即咱們須要在系統遷移後將plainColumn,即pwd進行刪除。那問題來了,如今業務代碼都是面向pwd進行編寫SQL的,把底層數據表中的存放明文的pwd刪除了,換用pwd_cipher進行解密獲得原文數據,那豈不是意味着業務方須要整改全部SQL,從而不使用即將要被刪除的pwd列?還記得咱們Encrypt-JDBC的核心意義所在嗎?
這也正是Encrypt-JDBC核心意義所在,即依據用戶提供的脫敏規則,將用戶SQL與底層數據庫表結構割裂開來,使得用戶的SQL編寫再也不依賴於真實的數據庫表結構。而用戶與底層數據庫之間的銜接、映射、轉換交由ShardingSphere進行處理。
是的,由於有logicColumn存在,用戶的編寫SQL都面向這個虛擬列,Encrypt-JDBC就能夠把這個邏輯列和底層數據表中的密文列進行映射轉換。因而遷移後的脫敏配置即爲:
encryptRule:
encryptors:
aes_encryptor:
type: aes
props:
aes.key.value: 123456abc
tables:
t_user:
columns:
pwd: # pwd與pwd_cipher的轉換映射
cipherColumn: pwd_cipher
encryptor: aes_encryptor
props:
query.with.cipher.column: true
其處理流程以下
至此,已在線業務脫敏整改解決方案所有敘述完畢。咱們提供了Java、Yaml、SpringBoot、SpringNameSpace多種方式供用戶選擇接入,力求知足業務不一樣的接入需求。該解決方案目前已在京東數科不斷落地上線,提供對內基礎服務支撐。
1. 自動化&透明化數據脫敏過程,用戶無需關注脫敏中間實現細節。
2. 提供多種內置、第三方(AKS)的脫敏策略,用戶僅需簡單配置便可使用。
3. 提供脫敏策略API接口,用戶可實現接口,從而使用自定義脫敏策略進行數據脫敏。
4. 支持切換不一樣的脫敏策略。
5. 針對已上線業務,可實現明文數據與密文數據同步存儲,並經過配置決定使用明文列仍是密文列進行查詢。可實如今不改變業務查詢SQL前提下,已上線系統對加密先後數據進行安全、透明化遷移。
1. 用戶項目使用Java語言進行編程。
2.後端數據庫爲MySQL、Oracle、PostgreSQL、SQLServer。
3. 用戶須要對數據庫表中某個或多個列進行脫敏(數據加密&解密)。
4. 兼容全部經常使用SQL;
Coding...
1. 用戶須要自行處理數據庫中原始的存量數據、洗數。
2. 使用脫敏功能+分庫分表功能,部分特殊SQL不支持,請參考SQL使用規範。
3. 脫敏字段沒法支持比較操做,如:大於小於、ORDER BY、BETWEEN、LIKE等
4. 脫敏字段沒法支持計算操做,如:AVG、SUM以及計算表達式
本篇文章介紹瞭如何使用ShardingSphere產品之一的Encrypt-JDBC進行接入,接入形式還能夠選擇使用SpringBoot、SpringNameSpace等,這種形態的接入端主要面向JAVA同構,並與業務代碼共同部署在生產環境中。面向異構語言,ShardingSphere還提供Encrypt-Proxy客戶端。Encrypt-Proxy是一款實現MySQL、PostgreSQL的二進制協議的服務器端產品,用戶可獨立部署Encrypt-Proxy服務,而且像使用普通MySQL、PostgreSQL數據庫同樣,使用例如Navicat第三方數據庫管理工具、JAVA鏈接池、命令行的方式訪問這臺具備脫敏功能的虛擬數據庫服務器。
脫敏功能屬於Apache ShardingSphere分佈式治理的功能範疇。事實上,Apache ShardingSphere這個生態還擁有其餘更強大的能力,例如數據分片、讀寫分離、分佈式事務、監控治理等。您甚至能夠選擇任意多種功能模塊進行疊加使用,例如同時使用數據脫敏+數據分片,或是數據分片+讀寫分離,再或者是監控治理+數據分片等。除了在功能層面的疊加選擇,ShardingSphere還提供了各類接入端形式,例如Sharding-JDBC或Sharding-Proxy等以知足你們不一樣場景需求
ShardingSphere從最初的僅支持分庫分表功能,到如今已造成包括數據分片、分佈式治理、分佈式事務等核心功能爲主的生態圈。這也標識着它不只僅是一款分佈式數據庫中間件,不只僅擁有分庫分表的能力,更是造成以數據分片、分佈式治理、分佈式事務爲核心的全方位解決方案生態體系,歡迎你們在官網瞭解更多內容,在gitHub關注咱們☺!
官網&gitHub
https://shardingsphere.apache...
https://github.com/apache/inc...
招賢納士
職位信息:
https://mp.weixin.qq.com/s/u3DhzAzVURsA8abUALWcLQ
招聘郵箱:
zhangliang@apache.org
• end •
加羣&
關注公衆號