當前位置: 妍妍網 > 碼農

被問懵了,加密後的數據如何進行模糊查詢?

2024-05-05碼農

加密後的數據對模糊查詢不是很友好,本篇就針對加密數據模糊查詢這個問題來展開講一講實作的思路。

為了數據安全我們在開發過程中經常會對重要的數據進行加密儲存,常見的有:密碼、手機號、電話號碼、詳細地址、銀行卡號、信用卡驗證碼等資訊,這些資訊對加解密的要求也不一樣,比如說密碼我們需要加密儲存,一般使用的都是不可逆的慢hash演算法,慢hash演算法可以避免暴力破解(典型的用時間換安全性)

在檢索時我們既不需要解密也不需要模糊尋找,直接使用密文完全匹配,但是手機號就不能這樣做,因為手機號我們要檢視原資訊,並且對手機號還需要支持模糊尋找,因此我們今天就針對可逆加解密的數據支持模糊查詢來看看有哪些實作方式。

在網上隨便搜尋了一下,關於【加密後的模糊查詢】 的貼文很多,順便整理了一下實作的方法,不得不說很多都是不靠譜的做法,甚至有一些沙雕做法,接下來我們就對這些做法來講講實作思路和優劣性。

如何對加密後的數據進行模糊查詢

我整理了一下對加密的數據模糊查詢大致分為三類做法,如下所示:

  • 沙雕做法(不動腦思考直男的思路,只管實作功能從不深入思考問題)

  • 常規做法(思考了查詢效能問題,也會使用一些儲存空間換效能等做法)

  • 超神做法(比較高端的做法從演算法層面上思考)

  • 我們就對這三種實作方法一一來講講實作思路和優劣性,首先我們先看沙雕做法。

    沙雕做法

  • 將所有數據載入到記憶體中進行解密,解密後透過程式演算法來模糊匹配

  • 將密文數據對映一份明文對映表,俗稱tag表,然後模糊查詢tag來關聯密文數據

  • 沙雕一

    我們先來看看第一個做法,將所有數據載入到記憶體中進行解密,這個如果數據量小的話可以使用這個方式來做,這樣做既簡單又實惠,如果數據量大的話那就是災難,我們來大致算一下。

    一個英文字母(不分大小寫)占一個字節的空間,一個中文漢字占兩個字節的空間,用DES來舉例,13800138000加密後的串HE9T75xNx6c5yLmS5l4r6Q==占24個字節。

    輕則上百兆,重則上千兆,這樣分分鐘給應用程式整成Out of memory,這樣做如果數據少只有幾百、幾千、幾萬條時是完全可以這樣做的,但是數據量大就強烈不建議了。

    沙雕二

    我們再來看第二個做法,將密文數據對映一份明文對映表,然後模糊查詢對映表來關聯密文數據,what???!!!那我們為什麽要對數據加密呢,直接不加密不是更好麽!

    我們既然對數據加密肯定是有安全訴求才會這樣做,增加一個明文的對映表就違背了安全訴求,這樣做既不安全也不方便完全是脫褲子放x,多此一舉,強且不推薦。

    常規做法

    我們接下來看看常規的做法,也是最廣泛使用的方法,此類方法及滿足的數據安全性,又對查詢友好。

    在資料庫實作加密演算法函式,在模糊查詢的時候使用decode(key) like '%partial%

    對密文數據進行分詞組合,將分詞組合的結果集分別進行加密,然後儲存到擴充套件列,查詢時透過key like '%partial%'

    常規一

    在資料庫中實作與程式一致的加解密演算法,修改模糊查詢條件,使用資料庫加解密函式先解密再模糊尋找,這樣做的優點是實作成本低,開發使用成本低,只需要將以往的模糊尋找稍微修改一下就可以實作,但是缺點也很明顯,這樣做無法利用資料庫的索引來最佳化查詢,甚至有一些資料庫可能無法保證與程式實作一致的加解密演算法,但是對於常規的加解密演算法都可以保證與應用程式一致。

    如果對查詢效能要求不是特別高、對數據安全性要求一般,可以使用常見的加解密演算法比如說AES、DES之類的也是一個不錯的選擇。

    如果公司有自己的演算法實作,並且沒有提供多端的演算法實作,要麽找個演算法好的人去研究吃透補全多端實作,要麽放棄使用這個辦法。

    常規二

    對密文數據進行分詞組合,將分詞組合的結果集分別進行加密,然後儲存到擴充套件列,查詢時透過key like '%partial%',這是一個比較劃算的實作方法,我們先來分析一下它的實作思路。

    先對字元進行固定長度的分組,將一個欄位拆分為多個,比如說根據4位元英文字元(半形),2個中文字元(全形)為一個檢索條件,舉個例子:

    ningyu1使用4個字元為一組的加密方式,第一組ning ,第二組ingy ,第三組ngyu ,第四組gyu1 … 依次類推。

    如果需要檢索所有包含檢索條件4個字元的數據比如:ingy ,加密字元後透過 key like 「%partial%」 查庫。

    我們都知道加密後長度會增長,增長的這部份長度儲存就是我們要花費的額外成本,典型的使用成本來換取速度,密文增長的振幅隨著演算法不同而不同以DES舉例,13800138000加密前占11個字節,加密後的串HE9T75xNx6c5yLmS5l4r6Q==占24個字節,增長是2.18倍,所以一個優秀的演算法是多麽的重要,能為公司節省不少成本,但是話又說回來演算法工程師的薪資也不低,所以我也不知道是節省成本還是增加成本,哈哈哈…你們自己算吧。

    回到主題,這個方法雖然可以實作加密數據的模糊查詢,但是對模糊查詢的字元長度是有要求的,以我上面舉的例子模糊查詢字元原文長度必須大於等於4個英文/數位,或者2個漢字,再短的長度不建議支持,因為分詞組合會增多從而導致儲存的成本增加,反而安全性降低。

    大家是否都對接過 淘寶、拼多多、JD他們的api,他們對平台訂單數據中的使用者敏感數據就是加密的同時支持模糊查詢,使用就是這個方法,下面我整理了幾家電商平台的密文欄位檢索方案的說明,感興趣的可以檢視下面連結

  • 淘寶密文欄位檢索方案:https://open.taobao.com/docV3.htm?docId=106213&docType=1

  • 阿裏巴巴文欄位檢索方案:https://jaq-doc.alibaba.com/docs/doc.htm?treeId=1&articleId=106213&docType=1

  • 拼多多密文欄位檢索方案:https://open.pinduoduo.com/application/document/browse?idStr=3407B605226E77F2

  • 京東密文欄位檢索方案:https://jos.jd.com/commondoc?listId=345

  • ps. 基本上都是一樣的,果然都是互相抄襲,連加密後的數據格式都一致。

    這個方法優點就是實作起來不算復雜,使用起來也較為簡單,算是一個折中的做法,因為會有擴充套件欄位儲存成本會有升高,但是可利用資料庫索引最佳化查詢速度,推薦使用這個方法。

    超神做法

    我們接下來看看優秀的做法,此類做法難度較高,都是從演算法層面來考慮,有些甚至會設計一個新演算法,雖然已有一些現成的演算法參考,但是大多都是半成品無法拿來直接使用,所以還是要有人去深入研究和整合到自己的套用中去。

    從演算法層面思考,甚至會設計一個新演算法來支持模糊尋找

    這個層面大多是專業演算法工程師的研究領域,想要設計一個有序的、非不可逆的、密文長度不能增長過快的演算法不是一件簡單的事情,大致的思路是這樣的,使用譯碼的方式進行加解密,保留密文和原文一樣的順序,從而支持密文模糊匹配,說的比較籠統因為我也不是這方面的專家沒有更深一步的研究過,所以我從網上找了一些資料可以參考一下。

  • 資料庫中字元數據的模糊匹配加密方法:https://www.jiamisoft.com/blog/6542-zifushujumohupipeijiamifangfa.html

  • 這裏提到的Hill密碼處理和模糊匹配加密方法FMES可以重點看看.

  • 一種基於BloomFilter的改進型加密文本模糊搜尋機制研究:http://kzyjc.cnjournals.com/html/2019/1/20190112.htm

  • 支持快速查詢的資料庫如何加密:https://www.jiamisoft.com/blog/5961-kuaisuchaxunshujukujiami.html

  • 基於Lucene的雲端搜尋與密文基礎上的模糊查詢:https://www.cnblogs.com/arthurqin/p/6307153.html

  • 基於Lucene的思路就跟我們上面介紹的常規做法二類似,對字元進行等長度分詞,將分詞後的結果集加密後儲存,只不過儲存的db不一樣,一個是關系型資料庫,一個是es搜尋引擎。

    雲端儲存中一種支持可驗證的模糊查詢加密方案http://jeit.ie.ac.cn/fileDZYXXXB/journal/article/dzyxxxb/2017/7/PDF/160971.pdf

    總結

    我們到這裏對加密數據的檢索方案全部介紹完了,我們首先提到的是網上搜尋隨處可見的沙雕做法,在這裏也講了不推薦使用這些沙雕做法,盡量使用常規做法,如果公司有專業演算法方向人才的話不妨可以考慮基於演算法層面的超神做法。

    總的來說從投入、產出比、及實作、使用成本來算的話常規做法二是非常推薦的。

    來源:ningyu1.github.io/20201230/encrypted-data-fuzzy-query.html

    >>

    END

    精品資料,超贊福利,免費領

    微信掃碼/長按辨識 添加【技術交流群

    群內每天分享精品學習資料

    最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎並行JVMMySQLRedisSpringSpringMVCSpringBootSpringCloud訊息佇列等多個型別),歡迎您的使用。

    👇👇

    👇點選"閱讀原文",獲取更多資料(持續更新中