MySql加密存储的数据,如何模糊搜索?
背景
蔚來被勒索 225 萬美元,大量數據遭泄露!
根據網絡上流傳的截圖顯示,黑客似乎掌握著蔚來內部員工數據 22800 條、車主用戶身份證數據 399000 條、用戶地址數據 6500000 條、注冊用戶數據 4850000 條、企業及企業代表聯系人數據 10000 條、訂單數據 490000 條、退單數據 90000 條,出售的金額以 0.1-0.25 比特幣不等。
蔚來公司和蔚來創始人李斌也都出來道歉,并承諾對因本次事件給用戶造成的損失承擔責任。
數據安全
現在企業都已經數字化辦公了,在提升效率的同時,數據安全也是重中之重,很多公司為了追求效率,卻忽略安全這方面的工作。從上面的報告看,蔚來這次泄露的數據包含:用戶身份證、地址,這些數據保密級別都是最高的,在數據庫存儲也應該要加密存儲。
而加密存儲就涉及以下幾個問題:
1、加密存儲的方式;
2、加密存儲后,數據如何展示;
3、加密存儲如何模糊搜索。
今天就給大家分享下,MySql數據加密的解決方案、以及如何解決以上的問題。
Mysql加密方案
Mysql本身自帶的加密方法,分為2種:
1、不可逆加密算法:
PASSWORD,ENCRYPT,MD5,SHA。
2、可逆的加密算法:
AES_ENCRYPT、AES_DECRYPT 和 ENCODE、DECODE。
以上兩組分別為可逆的加解密函數,都是返回一個二進制字符串,要以BLOB類型存儲。不過ENCODE與DECODE,在MySql 5.7后已經取消,并且安全性比較低,建議不要采用。
在項目開發中,比如密碼等少量的數據,不涉及顯示和搜索的業務需求,可以采用不可逆加密,但大部分數據,我們還是需要采用可逆的加密方式。
Mysql 加密存儲
下面我們以AES_ENCRYPT、AES_DECRYPT 為例子,來介紹下如何解決,數據加密存儲與查詢。
1、創建表
首先先創建一張表,只有一個字段data,用來存儲解密后的數據,sql語句如下:
CREATE TABLE `tab_aes` (`data` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8_general_ci')COMMENT='數據加密存儲表'COLLATE='utf8_general_ci'ENGINE=InnoDB;2、插入數據
通過Sql語句插入加密的數據,1ql語句如下:
INSERT INTO tab_aes VALUES( TO_BASE64( AES_ENCRYPT('要加密的內容','秘鑰') ) );TO_BASE64函數把加密的二進制轉換為Base64,方便我們查看。
插入的結果如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8cydETQM-1671712236301)(https://mmbiz.qpic.cn/sz_mmbiz_png/tJJDa2wmJiapJMlo01Tr0vjlrj8G49MZHrtkCQ0YJNicvPBPZqQqU6whxA1r1UWjZoeXVZ2I9knWNvXeyHxJSVdQ/640?wx_fmt=png)]
3、查詢返回解密數據
SELECT CAST( AES_DECRYPT( FROM_BASE64(tab_aes.data), '秘鑰') AS CHAR CHARACTER SET utf8 ) FROM tab_aes解密后,要用CAST把字符串編碼轉為UTF8,否則返回是亂碼。
模糊搜索
數據加密存儲與解密數據,這些都沒有太大問題,加密存儲產生最大的問題,就是模糊搜索,關于模糊搜索有以下方案:
1、數據預加載至內存數據庫
此方案是程序啟動的時候,預先把數據庫的數據解密,并加載至內存中,比如采用MongoDB,此方案存在的優缺點如下:
優點:
數據安全,查詢性能速度快
缺點:
服務器占用內存大;
數據表無法關聯查詢;
內存數據與數據庫要實時保存一致,需要額外工作量。
2、程序實時加載數據,并解密處理
此方案是,用戶觸發請求的時候,程序實時加載并解密,保存至內存,雖然此方案解決了與數據庫同步的問題,但也存在其他問題,此方案優缺點如下:
優點:
數據安全,查詢性能速度快、數據處理靈活。
缺點:
服務器內存不可控,瞬間內存容易飆升,可能導致服務器不穩定;
數據表無法關聯查詢。
3、在Sql語句處理模糊搜索
如果數據量比較少,以上兩種方案可能不會產生太大的影響,但對于大多數項目以上兩種方案還是不靠譜的。
在Sql語句處理模糊搜索,也有以下幾種方案:
3.1、實時解密搜索
直接在數據庫端,把加密的數據解密。
SELECT CAST( AES_DECRYPT( FROM_BASE64(tab_aes.data), '秘鑰') AS CHAR CHARACTER SET UTF8 ) FROM tab_aes WHERE CAST( AES_DECRYPT( FROM_BASE64(tab_aes.data), '秘鑰') AS CHAR CHARACTER SET UTF8 ) LIKE '要加密%'優點
搜索靈活
缺點:
無法利用索引,搜索性能慢;
數據需要先解密,導致性能慢。
3.2、字段冗余存儲
我們都知道MySql模糊搜索,只有當匹配開頭、或者匹配結尾的時候,索引才會生效。所以我們可以擴展一個字段,用來存儲開頭和結尾加密后的數據。
創建表sql語句如下,新增一個字段data_ext,并建立索引:
CREATE TABLE `tab_aes` ( `data` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8_general_ci', `data_ext` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8_general_ci', INDEX `data_ext` (`data_ext`) USING BTREE ) COMMENT='數據加密存儲表' COLLATE='utf8_general_ci' ENGINE=InnoDB ;比如,要加密的內容為:123456789,字段data_ext取字段data,開頭和結尾3個字符存儲,儲存格式為:AES(123) , AES(789),插入數據的sql語句如下:
INSERT INTO tab_aes VALUES( TO_BASE64( AES_ENCRYPT('要加密的內容','秘鑰')), CONCAT(TO_BASE64( AES_ENCRYPT('要加密','秘鑰')), ',', TO_BASE64( AES_ENCRYPT('內容','秘鑰'))) );存儲結果如下:
相應的模糊搜索sql語句如下:
SELECT CAST( AES_DECRYPT( FROM_BASE64(tab_aes.data), '秘鑰') AS CHAR CHARACTER SET UTF8 ) FROM tab_aesWHEREtab_aes.data_ext LIKE CONCAT(TO_BASE64(AES_ENCRYPT(('要加密'),'秘鑰')),'%')AND tab_aes.data_ext LIKE CONCAT('%',TO_BASE64(AES_ENCRYPT(('內容'),'秘鑰')))AND tab_aes.data_ext LIKE CONCAT(TO_BASE64(AES_ENCRYPT(('要加密'),'秘鑰')),'%', TO_BASE64(AES_ENCRYPT('內容','秘鑰')));通過Explain分析結果,該查詢sql語句索引是生效的。
此方案優點:
搜索性能高;
支持表關聯搜索。
此方案也有以下缺點:
1、匹配字符數是固定,如果業務有變,需要重新更新數據庫;
2、數據存儲需要額外工作量;
3、冗余數據,需要額外的存儲空間。
寫在最后
任何一種方案都有其優點,也有它的局限性,但有一點的是,數據安全是最重要的,任何企業切不可只為了業務發展,而忽略安全的重要性。
好了,今天就分享到這邊了,如果對您有幫助,歡迎點贊分享,謝謝!
- End -
推薦閱讀
用C#自己動手寫個操作系統,爽!
盤點5個C#實用的Word、PPT、Excel、Mail第三方庫
一個C#開發的Windows遠程桌面工具
盤點10個Web開發人員必備的最佳開發工具推薦
盤點10個.Net比較流行的開源的ORM框架
總結
以上是生活随笔為你收集整理的MySql加密存储的数据,如何模糊搜索?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 信号(signal)介绍
- 下一篇: 移动魔百盒UNT413A卡刷固件