数据库加密字段进行模糊查询详解

 更新时间:2022年09月05日 10:00:46   作者:jiaxwu  
这篇文章主要为大家介绍了数据库加密字段进行模糊查询详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

需求

对于一些敏感字段,比如手机号码、身份证、地址、银行卡号等,我们在存放进数据库前,可能需要对其进行加密。

大部分情况下,我们只需要支持等值查询。但是如果需要支持模糊查询,那么整段内容整体加密就不具备这个能力。

下面是几种解决办法,场景是我们需要根据手机号码的前缀进行匹配。

服务器端解密

因为服务器肯定是具备解密密文的能力的,因此最简单的方式就是把整个表的密文字段数据拉下来,在服务器端进行解密,然后再在服务器端进行匹配。

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
1234eHCMZqxNSLx/B37koArx/w
23459w1Pv8ik2H41s1KORLfPHA
3456vcFFFvi0mwAgIjdSQjcmSw
4567Tr/WaYfVySyMJhcZ78RFlA
56782wFeC6sgdXX7wmo0YcYY/Q
6789FfO9qD9XPx/lnJJuTfTfaA
7890Wufth7zOBLEy2LmepG5Taw
89011xR5MHRmlqOac5X6Cmn3kA

这些密文拼接起来的串为:

/egpaR5G9sMQUUWWz+3CLgeHCMZqxNSLx/B37koArx/w9w1Pv8ik2H41s1KORLfPHAvcFFFvi0mwAgIjdSQjcmSwTr/WaYfVySyMJhcZ78RFlA2wFeC6sgdXX7wmo0YcYY/QFfO9qD9XPx/lnJJuTfTfaAWufth7zOBLEy2LmepG5Taw1xR5MHRmlqOac5X6Cmn3kA

然后就可以支持前缀查询了(最少4位),比如前缀01234,我们可以按照上面的分片方式先分片,再拼接为查询串:

分片密文
0123/egpaR5G9sMQUUWWz+3CLg
1234eHCMZqxNSLx/B37koArx/w

查询串:

/egpaR5G9sMQUUWWz+3CLgeHCMZqxNSLx/B37koArx/w

可以看到查询串为上面的前缀,因此可以进行前缀查询!

代价

这种方式也是会有一定的代价的:

密文长度较长

比如手机号码是明文长度是11,但是按照4位分片的密文长度是198

分片长度不能太短

分片太短有安全问题,因此没办法支持过短的查询。

主要是因为切片过短,会很容易被猜出来每一位对应的密文。比如0-9的密文切片长度1切分:

分片密文
0hHjJXA0e+haw/+WZ1mFITA
1y7qHn2nn3Ne/6wNRiwl/Lg
2h0dmfkO5SUolFFLp8J2Y5A
3ma/XrJjPv2MXSXE7Y4xs8w
4Q9V4PXXPjJgdR7UChUMY1g
5Wo57z24UXLoBdQ7QzxlOqA
6fC+zrF4ga5TCb5Zu36KVrQ
7z+XqHaWmlAsCnIP6NnD3lg
8olm8cPYmLHCeD1jegauiWw
9hJS77tLMd2Ol5SU4dIbbpw

只有10种分片类型,如果对应的是手机号码字段,很容易根据统计每个数字的概率分布猜出每个数字对应的密文。

可能有多余结果

可能有两个不同分片对应相同密文,这时候就需要在服务器再过滤一遍。

参考

密文字段检索方案

实现

Golang实现基于AES+CBC+PKCS5Padding的可模糊查询加密

以上就是数据库加密字段进行模糊查询详解的详细内容,更多关于数据库加密字段模糊查询的资料请关注程序员之家其它相关文章!

相关文章

最新评论

?


http://www.vxiaotou.com