美團二面:加密後的數據如何進行模糊查詢??被問懵了。。

来源:https://www.cnblogs.com/javastack/archive/2022/08/31/16642982.html
-Advertisement-
Play Games

我們知道加密後的數據對模糊查詢不是很友好,本篇就針對加密數據模糊查詢這個問題來展開講一講實現的思路,希望對大家有所啟發。 為了數據安全我們在開發過程中經常會對重要的數據進行加密存儲,常見的有:密碼、手機號、電話號碼、詳細地址、銀行卡號、信用卡驗證碼等信息,這些信息對加解密的要求也不一樣,比如說密碼我 ...


我們知道加密後的數據對模糊查詢不是很友好,本篇就針對加密數據模糊查詢這個問題來展開講一講實現的思路,希望對大家有所啟發。

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

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

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

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

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

  • 沙雕做法(不動腦思考直男的思路,只管實現功能從不深入思考問題)
  • 常規做法(思考了查詢性能問題,也會使用一些存儲空間換性能等做法)
  • 超神做法(比較高端的做法從演算法層面上思考)

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

沙雕做法

  • 將所有數據載入到記憶體中進行解密,解密後通過程式演算法來模糊匹配
  • 將密文數據映射一份明文映射表,俗稱tag表,然後模糊查詢tag來關聯密文數據

沙雕一

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

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

條數 Bytes MB
100w 2400萬 22.89
1000w 2.4億 228.89
1億 24億 2288.89

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

推薦一個 Spring Boot 基礎實戰教程:

https://github.com/javastacks/spring-boot-best-practice

沙雕二

我們再來看第二個做法,將密文數據映射一份明文映射表,然後模糊查詢映射表來關聯密文數據,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,他們對平臺訂單數據中的用戶敏感數據就是加密的同時支持模糊查詢,使用就是這個方法,下麵我整理了幾家電商平臺的密文欄位檢索方案的說明,感興趣的可以查看下麵鏈接。

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

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

超神做法

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

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

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

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

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

總結

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

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

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

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 創作不易,感謝支持! fopen函數 頭文件:stdio.h 功能是打開一個文件,其聲明格式是: FILE *fopen(const char *filename, const char *mode); 文件指針名 = fopen(文件名,使用文件方式) “文件名”是被打開文件的文件名,類型是C風格 ...
  • GUI:Graphical User Interface(圖形用戶介面) 用圖形的方式,用來顯示電腦操作的界面 Java為GUI提供的API都存在java.awt和javax.Swing兩個包中 java.awt 包: awt是這三個單詞首字母的縮寫,翻譯過來是抽象視窗工具包,只不過這個包的API ...
  • (這裡寫自定義目錄標題)Java開發入門 博客內容是本人自學java過程,所以具體工具的下載步驟會省略。其中的部分下載和安裝步驟,引用了其他博主的相關文章。 Java語言 Java是目前世界上最流行的電腦編程語言,是一種可以編寫跨平臺應用軟體的面向對象的程式設計語言,也是當今使用率最高的編程語言。 ...
  • 前兩天從網上採集到一條短視頻數據(刷短視頻),發現六公主連排5部劉亦菲主演的電影!甚是震驚,太有牌面了,看了一下日子是8月25號,嗷,原來當天是劉亦菲的生日。巧了,正好也是我家柴犬旺財的3歲生日😀。 言歸正傳,我們看到這條數據的 標題:#劉亦菲35歲生日獲央視獨寵# 神仙姐姐生日快樂! 為了分析數 ...
  • 首先,進行springboot2.7之後,官方不推薦使用/META-INF/spring.factories,轉成和SPI比較類似的/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件, ...
  • 近日,項目中有一個耗時較長的Job存在CPU占用過高的問題,經排查發現,主要時間消耗在往MyBatis中批量插入數據。mapper configuration是用foreach迴圈做的,差不多是這樣。(由於項目保密,以下代碼均為自己手寫的demo代碼) <insert id="batchInsert ...
  • 鏡像倉庫管理 docker倉庫,用來管理鏡像。主要分為公共倉庫和私人倉庫。下麵介紹了公共倉庫Docker Hub、私人倉庫Registry和harbor。 DockerHUb倉庫管理 什麼是DockerHUb 保存和分發鏡像的最直接方法就是使用 Docker Hub。 ​ Docker Hub 是 ...
  • get邏輯: HashMap數據結構為數組加鏈表加紅黑樹、只有當鏈表數量大於8時、才將鏈表轉換為紅黑樹、時間複雜度由鏈表的O(N)轉換為紅黑樹的O(logN) // 主要看getNode下的方法、傳入key的hash值和key public V get(Object key) { Node<K,V> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...