網站首頁 編程語言 正文
需求
對于一些敏感字段,比如手機號碼、身份證、地址、銀行卡號等,我們在存放進數據庫前,可能需要對其進行加密。
大部分情況下,我們只需要支持等值查詢。但是如果需要支持模糊查詢,那么整段內容整體加密就不具備這個能力。
下面是幾種解決辦法,場景是我們需要根據手機號碼的前綴進行匹配。
服務器端解密
因為服務器肯定是具備解密密文的能力的,因此最簡單的方式就是把整個表的密文字段數據拉下來,在服務器端進行解密,然后再在服務器端進行匹配。
findRecords(prefix) {
records = getAllRecords()
finds = []
for (record : records) {
phone = decrypt(record.phone)
if (phone.hasPrefix(prefix)) {
finds.push(record)
}
}
return finds
}
如果數據量很小,那么這種做法也許還能夠接受。但是只要數據量上去,那么效率就會很低,而且還需要通過網絡IO把整個表的數據傳輸到服務器端。
數據庫端解密
上面的做法需要把整個表的數據傳輸到服務器端,那么我們只需要能夠在數據庫進行匹配,就不需要傳輸整個表了。因此我們也可以在數據庫實現解密算法,在匹配的時候用解密算法解密密文,就能夠進行模糊匹配了。
findRecords(prefix) {
return query("select * from table where decrypt(phone) like '?%'", prefix)
}
這個做法也是需要遍歷整個數據庫,因此只適合數據量比較小的情況下;而且需要把密鑰傳給數據庫,增加了密鑰泄露的風險。
字符串分片
上面的做法我們都沒有用到數據庫的索引能力,正常情況下,前綴匹配我們是可以使用到索引的,比如where phone like 'prefix%'。如果加密后的密文,也能夠走索引,那么我們就不需要遍歷整個數據表了。
比如我們可以根據4位作為一個檢索條件,將手機號碼拆分位多個分片:比如手機號012345678901,我們可以拆分并對分片進行加密:
分片 | 密文 |
---|---|
0123 | /egpaR5G9sMQUUWWz+3CLg |
1234 | eHCMZqxNSLx/B37koArx/w |
2345 | 9w1Pv8ik2H41s1KORLfPHA |
3456 | vcFFFvi0mwAgIjdSQjcmSw |
4567 | Tr/WaYfVySyMJhcZ78RFlA |
5678 | 2wFeC6sgdXX7wmo0YcYY/Q |
6789 | FfO9qD9XPx/lnJJuTfTfaA |
7890 | Wufth7zOBLEy2LmepG5Taw |
8901 | 1xR5MHRmlqOac5X6Cmn3kA |
這些密文拼接起來的串為:
/egpaR5G9sMQUUWWz+3CLgeHCMZqxNSLx/B37koArx/w9w1Pv8ik2H41s1KORLfPHAvcFFFvi0mwAgIjdSQjcmSwTr/WaYfVySyMJhcZ78RFlA2wFeC6sgdXX7wmo0YcYY/QFfO9qD9XPx/lnJJuTfTfaAWufth7zOBLEy2LmepG5Taw1xR5MHRmlqOac5X6Cmn3kA
然后就可以支持前綴查詢了(最少4位),比如前綴01234,我們可以按照上面的分片方式先分片,再拼接為查詢串:
分片 | 密文 |
---|---|
0123 | /egpaR5G9sMQUUWWz+3CLg |
1234 | eHCMZqxNSLx/B37koArx/w |
查詢串:
/egpaR5G9sMQUUWWz+3CLgeHCMZqxNSLx/B37koArx/w
可以看到查詢串為上面的前綴,因此可以進行前綴查詢!
代價
這種方式也是會有一定的代價的:
密文長度較長
比如手機號碼是明文長度是11,但是按照4位分片的密文長度是198
分片長度不能太短
分片太短有安全問題,因此沒辦法支持過短的查詢。
主要是因為切片過短,會很容易被猜出來每一位對應的密文。比如0-9的密文切片長度1切分:
分片 | 密文 |
---|---|
0 | hHjJXA0e+haw/+WZ1mFITA |
1 | y7qHn2nn3Ne/6wNRiwl/Lg |
2 | h0dmfkO5SUolFFLp8J2Y5A |
3 | ma/XrJjPv2MXSXE7Y4xs8w |
4 | Q9V4PXXPjJgdR7UChUMY1g |
5 | Wo57z24UXLoBdQ7QzxlOqA |
6 | fC+zrF4ga5TCb5Zu36KVrQ |
7 | z+XqHaWmlAsCnIP6NnD3lg |
8 | olm8cPYmLHCeD1jegauiWw |
9 | hJS77tLMd2Ol5SU4dIbbpw |
只有10種分片類型,如果對應的是手機號碼字段,很容易根據統計每個數字的概率分布猜出每個數字對應的密文。
可能有多余結果
可能有兩個不同分片對應相同密文,這時候就需要在服務器再過濾一遍。
參考
密文字段檢索方案
實現
Golang實現基于AES+CBC+PKCS5Padding的可模糊查詢加密
原文鏈接:https://juejin.cn/post/7139490768426631198
相關推薦
- 2022-05-14 Python函數中的作用域規則詳解_python
- 2022-11-03 ahooks?useVirtualList?封裝虛擬滾動列表_React
- 2022-10-23 C++進程的創建和進程ID標識詳細介紹_C 語言
- 2023-11-12 解決yolov3編譯中出現的問題:darknet make include/darknet.h:16
- 2022-09-09 python?獲取星期字符串的實例_python
- 2022-06-26 Android?app啟動節點與上報啟動實例詳解_Android
- 2022-06-07 python字符串的一些常見實用操作_python
- 2022-06-16 Go基礎教程系列之回調函數和閉包詳解_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支