Apache ShardingSphere數據脫敏全解決方案詳解

Apache ShardingSphere數據脫敏全解決方案詳解html

做者簡介git

潘娟,京東數科高級DBA,主要負責京東數科數據庫中間件開發、數據庫運維自動化平臺開發、生產數據庫運維工做。屢次參與京東6.1八、11.11等大促活動的護航工做。曾負責京東數科數據庫自動化平臺設計與開發項目,現專一於Apache ShardingSphere分佈式數據庫中間件開發。樂於在數據庫、自動化、分佈式、中間件等相關領域進行學習和探索。github

1、背景算法

安全控制一直是治理的重要環節,數據脫敏屬於安全控制的範疇。對互聯網公司、傳統行業來講,數據安全一直是極爲重視和敏感的話題。數據脫敏是指對某些敏感信息經過脫敏規則進行數據的變形,實現敏感隱私數據的可靠保護。涉及客戶安全數據或者一些商業性敏感數據,如身份證號、手機號、卡號、客戶號等我的信息按照相關部門規定,都須要進行數據脫敏。sql

在真實業務場景中,相關業務開發團隊則每每須要針對公司安所有門需求,自行實行並維護一套加解密系統,而當脫敏場景發生改變時,自行維護的脫敏系統每每又面臨着重構或修改風險。此外,對於已經上線的業務,如何在不修改業務邏輯、業務SQL的狀況下,透明化、安全低風險地實現無縫進行脫敏改造呢?數據庫

Apache ShardingSphere根據業界對脫敏的需求及業務改造痛點,提供了一套完整、安全、透明化、低改形成本的數據脫敏整合解決方案。apache

2、前序編程

Apache ShardingSphere是一套開源的分佈式數據庫中間件解決方案組成的生態圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(規劃中)這3款相互獨立,卻又可以混合部署配合使用的產品組成。它們均可以提供標準化的數據分片、分佈式事務和分佈式治理功能,可適用於如Java同構、異構語言、容器、雲原生等各類多樣化的應用場景。後端

數據脫敏模塊屬於ShardingSphere分佈式治理這一核心功能下的子功能模塊。它經過對用戶輸入的SQL進行解析,並依據用戶提供的脫敏配置對SQL進行改寫,從而實現對原文數據進行加密,並將原文數據(可選)及密文數據同時存儲到底層數據庫。在用戶查詢數據時,它又從數據庫中取出密文數據,並對其解密,最終將解密後的原始數據返回給用戶。Apache ShardingSphere分佈式數據庫中間件自動化&透明化了數據脫敏過程,讓用戶無需關注數據脫敏的實現細節,像使用普通數據那樣使用脫敏數據。此外,不管是已在線業務進行脫敏改造,仍是新上線業務使用脫敏功能,ShardingSphere均可以提供一套相對完善的解決方案。安全

3、需求場景分析

對於數據脫敏的需求,在現實的業務場景中通常分爲兩種狀況:

  1. 新業務上線,安所有門規定需將涉及用戶敏感信息,例如銀行、手機號碼等進行加密後存儲到數據庫,在使用的時候再進行解密處理。由於是全新系統,於是沒有存量數據清洗問題,因此實現相對簡單。

  2. 已上線業務,以前一直將明文存儲在數據庫中。相關部門忽然須要對已上線業務進行脫敏整改。這種場景通常須要處理三個問題:

    a) 歷史數據須要如何進行脫敏處理,即洗數。

    b) 如何能在不改動業務SQL和邏輯狀況下,將新增數據進行脫敏處理,並存儲到數據庫;在使用時,再進行解密取出。

    c) 如何較爲安全、無縫、透明化地實現業務系統在明文與密文數據間的遷移。

4、處理流程詳解

總體架構

ShardingSphere提供的Encrypt-JDBC和業務代碼部署在一塊兒。業務方需面向Encrypt-JDBC進行JDBC編程。因爲Encrypt-JDBC實現全部JDBC標準接口,業務代碼無需作額外改造便可兼容使用。此時,業務代碼全部與數據庫的交互行爲交由Encrypt-JDBC負責。業務只需提供脫敏規則便可。做爲業務代碼與底層數據庫中間的橋樑,Encrypt-JDBC即可攔截用戶行爲,並在改造行爲後與數據庫交互。

1

Encrypt-JDBC將用戶發起的SQL進行攔截,並經過SQL語法解析器進行解析、理解SQL行爲,再依據用戶傳入的脫敏規則,找出須要脫敏的字段和所使用的加解密器對目標字段進行加解密處理後,再與底層數據庫進行交互。

ShardingSphere會將用戶請求的明文進行加密後存儲到底層數據庫;並在用戶查詢時,將密文從數據庫中取出進行解密後返回給終端用戶。

ShardingSphere經過屏蔽對數據的脫敏處理,使用戶無需感知解析SQL、數據加密、數據解密的處理過程,就像在使用普通數據同樣使用脫敏數據。

脫敏規則

在詳解整套流程以前,咱們須要先了解下脫敏規則與配置,這是認識整套流程的基礎。脫敏配置主要分爲四部分:數據源配置,加密器配置,脫敏表配置以及查詢屬性配置,其詳情以下圖所示:

2

數據源配置:是指DataSource的配置。

加密器配置:是指使用什麼加密策略進行加解密。目前ShardingSphere內置了兩種加解密策略:AES/MD5。用戶還能夠經過實現ShardingSphere提供的接口,自行實現一套加解密算法。

脫敏表配置:用於告訴ShardingSphere數據表裏哪一個列用於存儲密文數據(cipherColumn)、哪一個列用於存儲明文數據(plainColumn)以及用戶想使用哪一個列進行SQL編寫(logicColumn)。

如何理解用戶想使用哪一個列進行SQL編寫(logicColumn)

咱們能夠從Encrypt-JDBC存在的意義來理解。Encrypt-JDBC最終目的是但願屏蔽底層對數據的脫敏處理,也就是說咱們不但願用戶知道數據是如何被加解密的、如何將明文數據存儲到plainColumn,將密文數據存儲到cipherColumn。換句話說,咱們不但願用戶知道plainColumn和cipherColumn的存在和使用。因此,咱們須要給用戶提供一個概念意義上的列,這個列能夠脫離底層數據庫的真實列,它能夠是數據庫表裏的一個真實列,也能夠不是,從而使得用戶能夠隨意改變底層數據庫的plainColumn和cipherColumn的列名。或者刪除plainColumn,選擇永遠再也不存儲明文,只存儲密文。只要用戶的SQL面向這個邏輯列進行編寫,並在脫敏規則裏給出logicColumn和plainColumn、cipherColumn之間正確的映射關係便可。

爲何要這麼作呢?答案在文章後面,即爲了讓已上線的業務能無縫、透明、安全地進行數據脫敏遷移。

查詢屬性的配置:當底層數據庫表裏同時存儲了明文數據、密文數據後,該屬性開關用於決定是直接查詢數據庫表裏的明文數據進行返回,仍是查詢密文數據經過Encrypt-JDBC解密後返回。

脫敏處理過程

舉個栗子,假如數據庫裏有一張表叫作t_user,這張表裏實際有兩個字段pwd_plain,用於存放明文數據、pwd_cipher,用於存放密文數據,同時定義logicColumn爲pwd。那麼,用戶在編寫SQL時應該面向logicColumn進行編寫,即INSERT INTO t_user SET pwd = '123'。ShardingSphere接收到該SQL,經過用戶提供的脫敏配置,發現pwd是logicColumn,因而便對邏輯列及其對應的明文數據進行脫敏處理。能夠看出ShardingSphere將面向用戶的邏輯列與面向底層數據庫的明文列和密文列進行了列名以及數據的脫敏映射轉換。以下圖所示:

3

這也正是Encrypt-JDBC核心意義所在,即依據用戶提供的脫敏規則,將用戶SQL與底層數據表結構割裂開來,使得用戶的SQL編寫再也不依賴於真實的數據庫表結構。而用戶與底層數據庫之間的銜接、映射、轉換交由ShardingSphere進行處理。爲何咱們要這麼作?仍是那句話:爲了讓已上線的業務能無縫、透明、安全地進行數據脫敏遷移。

爲了讓讀者更清晰瞭解到Encrypt-JDBC的核心處理流程,下方圖片展現了使用Encrypt-JDBC進行增刪改查時,其中的處理流程和轉換邏輯,以下圖所示。

4

5、解決方案詳解

在瞭解了ShardingSphere脫敏處理流程後,便可將脫敏配置、脫敏處理流程與實際場景進行結合。全部的設計開發都是爲了解決業務場景遇到的痛點。那麼面對以前提到的業務場景需求,又應該如何使用ShardingSphere這把利器來知足業務需求呢?

新上線業務

業務場景分析:新上線業務因爲一切從零開始,不存在歷史數據清洗問題,因此相對簡單。

解決方案說明:選擇合適的加密器,如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配置便可。總體處理流程以下圖所示:

5

已上線業務改造

業務場景分析:因爲業務已經在線上運行,數據庫裏必然存有大量明文歷史數據。如今的問題是如何讓歷史數據得以加密清洗、如何讓增量數據得以加密處理、如何讓業務在新舊兩套數據系統之間進行無縫、透明化遷移。

解決方案說明:在提供解決方案以前,咱們先來頭腦風暴一下:首先,既然是舊業務須要進行脫敏改造,那必定存儲了很是重要且敏感的信息。這些信息含金量高且業務相對基礎重要。若是搞錯了,整個團隊KPI就再見了。因此不可能一上來就停業務,禁止新數據寫入,再找個加密器把歷史數據所有加密清洗,再把以前重構的代碼部署上線,使其能把存量和增量數據進行在線加密解密。如此簡單粗暴的方式,按照歷史經驗來談,必定涼涼。

那麼另外一種相對安全的作法是:從新搭建一套和生產環境如出一轍的預發環境,而後經過相關遷移洗數工具把生產環境的存量原文數據加密後存儲到預發環境,而新增數據則經過例如MySQL主從複製及業務方自行開發的工具加密後存儲到預發環境的數據庫裏,再把重構後能夠進行加解密的代碼部署到預發環境。這樣生產環境是一套以明文爲核心的查詢修改的環境;預發環境是一套以密文爲核心加解密查詢修改的環境。在對比一段時間無誤後,能夠夜間操做將生產流量切到預發環境中。此方案相對安全可靠,只是時間、人力、資金、成本較高,主要包括:預發環境搭建、生產代碼整改、相關輔助工具開發等。除非無路可走,不然業務開發人員通常是從入門到放棄。

業務開發人員最但願的作法是:減小資金費用的承擔、最好不要修改業務代碼、可以安全平滑遷移系統。因而,ShardingSphere的脫敏功能模塊便應用而生。可分爲三步進行:

  1. 系統遷移前

    假設系統須要對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上額外存儲了新增數據的密文數據,其處理流程以下圖所示:

    6

    新增數據在插入時,就經過Encrypt-JDBC加密爲密文數據,並被存儲到了cipherColumn。而如今就須要處理歷史明文存量數據。因爲Apache ShardingSphere目前並未提供相關遷移洗數工具,此時須要業務方自行將pwd中的明文數據進行加密處理存儲到pwd_cipher。

  2. 系統遷移中

    新增的數據已被Encrypt-JDBC將密文存儲到密文列,明文存儲到明文列;歷史數據被業務方自行加密清洗後,將密文也存儲到密文列。也就是說如今的數據庫裏即存放着明文也存放着密文,只是因爲配置項中的query.with.cipher.column=false,因此密文一直沒有被使用過。如今咱們爲了讓系統能切到密文數據進行查詢,須要將脫敏配置中的query.with.cipher.column設置爲true。在重啓系統後,咱們發現系統業務一切正常,可是Encrypt-JDBC已經開始從數據庫裏取出密文列的數據,解密後返回給用戶;而對於用戶的增刪改需求,則依舊會把原文數據存儲到明文列,加密後密文數據存儲到密文列。

    雖然如今業務系統經過將密文列的數據取出,解密後返回;可是,在存儲的時候仍舊會存一份原文數據到明文列,這是爲何呢?答案是:爲了可以進行系統回滾。由於只要密文和明文永遠同時存在,咱們就能夠經過開關項配置自由將業務查詢切換到cipherColumn或plainColumn。也就是說,若是將系統切到密文列進行查詢時,發現系統報錯,須要回滾。那麼只需將query.with.cipher.column=false,Encrypt-JDBC將會還原,即又從新開始使用plainColumn進行查詢。處理流程以下圖所示:

    7

  3. 系統遷移後

    因爲安全審計部門要求,業務系統通常不可能讓數據庫的明文列和密文列永久同步保留,咱們須要在系統穩定後將明文列數據刪除。即咱們須要在系統遷移後將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

    其處理流程以下:

    8

至此,已在線業務脫敏整改解決方案所有敘述完畢。咱們提供了Java、Yaml、SpringBoot、SpringNameSpace多種方式供用戶選擇接入,力求知足業務不一樣的接入需求。該解決方案目前已在京東數科不斷落地上線,提供對內基礎服務支撐。

6、中間件脫敏服務優點

  1. 自動化&透明化數據脫敏過程,用戶無需關注脫敏中間實現細節。
  2. 提供多種內置、第三方(AKS)的脫敏策略,用戶僅需簡單配置便可使用。
  3. 提供脫敏策略API接口,用戶可實現接口,從而使用自定義脫敏策略進行數據脫敏。
  4. 支持切換不一樣的脫敏策略。
  5. 針對已上線業務,可實現明文數據與密文數據同步存儲,並經過配置決定使用明文列仍是密文列進行查詢。可實如今不改變業務查詢SQL前提下,已上線系統對加密先後數據進行安全、透明化遷移。

7、適用場景說明

  1. 用戶項目使用Java語言進行編程。
  2. 後端數據庫爲MySQL、Oracle、PostgreSQL、SQLServer。
  3. 用戶須要對數據庫表中某個或多個列進行脫敏(數據加密&解密)。
  4. 兼容全部經常使用SQL;

8、限制條件

  1. 用戶須要自行處理數據庫中原始的存量數據、洗數。
  2. 使用脫敏功能+分庫分表功能,部分特殊SQL不支持,請參考SQL使用規範
  3. 脫敏字段沒法支持比較操做,如:大於小於、ORDER BY、BETWEEN、LIKE等
  4. 脫敏字段沒法支持計算操做,如:AVG、SUM以及計算表達式

9、後續

本篇文章介紹瞭如何使用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等以知足你們不一樣場景需求

10、寫在最後

ShardingSphere從最初的僅支持分庫分表功能,到如今已造成包括數據分片、分佈式治理、分佈式事務等核心功能爲主的生態圈。這也標識着它不只僅是一款分佈式數據庫中間件,不只僅擁有分庫分表的能力,更是造成以數據分片、分佈式治理、分佈式事務爲核心的全方位解決方案生態體系,歡迎你們在官網瞭解更多內容,在gitHub關注咱們☺!

相關文章
相關標籤/搜索