敏感数据加密后如何实现sql模糊查询
|
admin
2024年12月9日 8:39
本文热度 444
|
在项目开发中都会要求保护用户的敏感信息(如用户的手机号码、身份证号),一般不可以直接将敏感信息的明文数据存储在数据库中。但是在业务中又需要对一些敏感信息实现模糊查询的功能,此时我们应该怎么解决这个问题呢?下面我们介绍敏感信息加密后实现模糊查询的功能的几种常见的解决方案。
1、内存解密方案
如果在数据库里面的数据已经加密了,此时我们将这些数据查询到内存中,然后进行解密操作,最后在解密后的数据中进行模糊查询来筛选出符合条件的数据。
内存解密方案的优点是简单方便,缺点是每次将加密后的数据整表加载到内存中然后解密再匹配,随着业务的发展,业务数据量会越来越大,那么很容易造成OOM。
2、明文映射查询方案
如果要查询186手机号开头的用户信息,首先通过186手机号在明文表中查询对应的用户id,然后通过用户id去用户表中查询对应的用户数据。
明文映射查询方案使用明文映射表来存储敏感字段,实际上相当于敏感字段没有加密存储,看似解决了实际上并没有解决。
3、加密函数方案
加密函数方案其实就是借助Mysql的加密函数,我们在数据库中使用和业务代码中一样的加密算法,对添加到数据库的敏感信息先加密保存,如下所示的加密插入:
SET @sensitive_text = "18698746523';
SET @encryption_key = "longxiabiancheng";
INSERT into user(name, phone) VALUES
("longxiabiancheng", AES_ENCRYPT(@sensitive_text, @encryption_key));
然后每次去查询的时候都会在where条件上对敏感数据字段使用加密函数来进行查询,如:
select * from user where AES_DECRYPT(phone,'key') like '%186';
加密函数方案实现成本比较低、开发成本上也简单,但是这种方式存在如下的弊端:
(1)敏感数据的字段无法使用数据库的索引来进行优化。
(2)在一些数据库中可能无法保证加密函数与业务代码中的加密方式一样。
4、分片加密方案
分片加密的方案是在明文映射查询方案的基础上进行延伸优化,核心的思想是将敏感数据分词,然后对这些分词分别加密后再拼接组合在一起得到一串最终的密文,将这个最终的密文保存到数据库中,如下是将手机号分段之后的密文的保存和查询的流程图:
假设有用户手机号码18168018974,我们按照前前3位、中间4位和尾号4位进行分词之后,对这几段分别的加密,如下所示:
181 | 6801 | 8974 |
0eJ1hEs6U3l= | 01qwers6U4l= | 0eJ1hEpoiu1= |
然后将这些分词加密后密文组合拼接起来,如下:
0eJ1hEs6U3l=01qwers6U4l=0eJ1hEpoiu1=
将这个拼接后的密文保存到数据库就是18168018974手机号的加密最终保存结果。
查询的时候,假设业务人员通过手机号码的前3位置查询,那么我们将前3位加密后得到密文A1,通过密文A1去模糊匹配得到结果。
那么针对普通的字符如何分词呢?假设有普通字符long1234,如果要让其支持模糊查询,此时我们按照4位一组进行分词如下所示:
一般来讲,分片加密方案中需要一定的限制:
(1)业界常用的分词方案是4个英文数字或者2个汉字一组,再短的长度不建议支持,因为分词组合越多就会导致存储的成本增加,反而安全性降低。
(2)如果支持敏感字段的模糊检索,那么加密的密文随原文长度增长而增加。
总结:
(1)当前主流的解决方案是分片加密方案,这种方案是以空间成本换取的,相比于存储原文,密文比原文增长了好几倍。
(2)内存解密方案和明文映射查询方案一般是不推荐使用。
(3)数据库加密函数方案,存在无法使用数据库索引和加密方式无法与业务代码中保持一致等弊端。
该文章在 2024/12/9 14:55:32 编辑过