当前位置: 首页 > article >正文

【MySQL】敏感数据加密后如何模糊查询?

往期文章:

【MySQL】索引

【MySQL】索引底层的数据结构 B+Tree

【MySQL】SQL语句执行流程

【MySQL】order by 的排序策略

【MySQL】explain 执行计划各字段解析


一、前言

在日常开发中,我们通常需要对敏感数据进行加密存储,如:手机号、身份证号码、银行卡号等。

但是此时就会出现一个问题,这些信息对加解密的要求也不一样,比如说密码,一般使用的都是不可逆的慢 hash 算法,慢 hash 算法可以避免暴力破解(典型的用时间换安全性)。 

在检索时我们既不需要解密也不需要模糊查找,直接使用密文完全匹配,但是手机号就不能这样做,因为手机号我们要查看原信息,并且对手机号还需要支持模糊查找。

关于这个问题,有多种解决方案,这些方案也是各有优劣,下面就一起来看看都有哪些方案。

二、先解密,再匹配

具体的做法就是将所有数据加载到内存中进行解密,解密后通过程序算法来模糊匹配。

一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。

就用 DES 加密算法来举例,hello world 加密后的密文是 def3f8ea781a12413b35b1c41f13ab32 占32个字节

条数BytesMB
100w3200万30.52
1000w3.2亿305.18
1亿32亿3051.76

可以看出,这种做法实现很简单,但是也存在一个很明显的问题,数据量小时完全没问题,一旦数据量增大,很容易就会导致 OOM,简直就是灾难!

所以不建议采用!!!

 

二、映射表 

将密文数据映射一份明文映射表,然后模糊查询映射表来关联密文数据。

那为什么还要对数据加密呢,直接不加密不是更好么!

我们既然对数据加密肯定是有安全诉求才会这样做,增加一个明文的映射表就违背了安全诉求,这样做既不安全也不方便完全是画蛇添足,多此一举。

所以不建议采用!!! 

 

三、数据库层面加密 

在数据库中实现与程序一致的加解密算法,修改模糊查询条件,使用数据库加解密函数先解密再模糊查找,这样做的优点是实现成本低,开发使用成本低,只需要将以往的模糊查找稍微修改一下就可以实现。

但是缺点也很明显,这样做无法利用数据库的索引来优化查询,甚至有一些数据库可能无法保证与程序实现一致的加解密算法,但是对于常规的加解密算法都可以保证与应用程序一致。

如果对查询性能要求不是特别高、对数据安全性要求一般,可以使用常见的加解密算法比如说AES、DES之类的也是一个不错的选择。

如果公司有自己的算法实现,并且没有提供多端的算法实现,要么找个算法好的人去研究吃透补全多端实现,要么放弃使用这个办法。

 

四、分词 

普通的加密模式下,整段内容会被整体加密,密文就不再具备被模糊查询的功能。

考虑到某些字段存在模糊查询的求,可以使用一种高级的加密模式,加密后的密文仍然可以支持模糊查询功能。

在普通加密方式下,我们在数据库检索该加密数据的时候必须用全文匹配。如姓名:“张大铁”,用普通方式加密后成为 “DQ21aTz/oe9qT2Xje1tTcddQ”,在数据库查询时,如果希望获取关于 ”张大铁” 的记录,则对应筛选条件就是筛选出加密姓名为 “DQ21aTz/oe9qT2Xje1tTcddQ” 的记录。

然而,如果是想检索姓名中含有 “大铁” 的人的记录,原本可以用数据库模糊查询(如 SQL 的 like  语句)方式获取,现在加密后就无法满足这样的要求了。

此时便可以采用对密文数据进行分词组合,将分词组合的结果集分别进行加密,然后存储到扩展列的方式,查询时通过 key like '%partial%',这是一个比较划算的实现方法。

具体做法:根据4位英文字符(半角),2个中文字符(全角)为一个检索条件。将一个字段拆分为多个。

比如:qiuxuan,使用4个字符为一组的加密方式。

第一组 qiux ,第二组 iuxu ,第三组 uxua ,第四组 xuan … 依次类推

如果需要检索所有包含检索条件 4 个字符的数据 比如:uxua,加密字符后通过 key like “%partial%”  查库。 

但是使用这种方式也有一定代价:

• 支持模糊查询加密方式,产出的密文比较长

• 支持的模糊查询子句长度必须大于等于4个英文/数字,或者2个汉字。不支持过短的查询(出于安全考虑);

• 返回的结果列表中有可能有多余的结果,需要增加筛选的逻辑:对记录先解密,再筛选;

对每一个字段都需要独立设置这个字段的加密模式,而且加密后密文长度会膨胀几倍以上,这是需要考虑的点,使用前需根据应用场景确认每个字段的加密方案,一旦加密开始之后,再更改成本就较高了。

这个方法优点就是实现起来不算复杂,使用起来也较为简单,算是一个折中的做法,因为会有扩展字段存储成本会有升高,但是可利用数据库索引优化查询速度,所以还是比较推荐使用这个方法。 

 

参考文章:

被问懵了,加密后的数据如何进行模糊查询?icon-default.png?t=O83Ahttps://cloud.tencent.com/developer/article/2085806

一  叶  知  秋,奥  妙  玄  心 


http://www.kler.cn/a/303561.html

相关文章:

  • js像循环数组那样循环一个数字,Array.from()
  • ES6更新的内容中什么是proxy
  • 插入排序——希尔排序
  • 【洛谷】T539823 202411D Phoenix
  • 供应链管理、一件代发系统功能及源码分享 PHP+Mysql
  • 字节青训营 数字魔法的加一操作
  • HarmonyOS】ArkTS学习之基于TextTimer的简易计时器的elapsedTime最小时间单位问题
  • Remix 学习 - 路由模块(Route Module)
  • 利用LM-Gaussian增强稀疏视图3D重建:利用大型模型先验实现高质量场景合成
  • ZoneTree: 高性能ACID兼容的.NET有序键值数据库
  • 使用vue2+axios+chart.js画折线图 ,出现 RangeError: Maximum call stack size exceeded 错误
  • 算法提高模板LCA
  • Unity Behavior Designe 可视化有限状态机(Composites篇)
  • Docker和Docker-compose
  • LSS如何创建视锥
  • HAL库学习梳理——UART
  • HarmonyOS NEXT应用开发性能实践总结
  • 太牛了!顺丰丰语大语言模型:已应用于20余个场景
  • 数据结构实验1
  • 电力系统调度控制台的功能有哪些
  • 【devops】devops-git之介绍以及日常使用
  • Winform中引入WPF控件后键盘输入无响应
  • Vue.js 中的 DOM 更新之后执行某些操作
  • uniapp与webview直接进行传值
  • vscode ssh离线远程连接ubuntu调试
  • python学习第九节:爬虫实战-抓取地址库