数据库加密后怎么做模糊查询?

数据库加密可以保障数据的安全,但是也会带来很多的问题,其中有一个比较关键的就是数据的模糊查询的问题。

当我们通过加密后把密文存到数据库中的时候,在通过明文进行模糊查询是不生效的。

比如Hello加密后的内容是363164846D8200899E314897E64A7420,那么当我想用Ho来做模糊查询时候,那么他的密文是71AAFD38484F3160708C6A6D2D5F736B,这两个密文可以说是没有任何关系的,所以,是无法直接做模糊查询的。那么如何解决这个问题呢?

先解密在查询

一种比较常见的方法,就是把要查询的表中的所有符合条件的数据,都加载到应用内存中,在内存中逐个解密,然后再做模糊匹配。

这个方案的优点就是实现简单,缺点也很明显,需要把所有数据都加载到内存中,容易导致OOM。

明文映射表

还有人提出过说单独建一张表,其中保存明文和目标表之间的映射,需要模糊查询的时候先去明文映射表中查到主键,然后再去目标表查询数据。

但是这个方案基本上是属于自欺欺人,因为一旦数据被拖库,还是会丢。不推荐。

数据库解密函数

加密的时候如果用了函数的话,解密的时候我们也可以借助函数来做解密,同时做模糊查询,比如加密时使用了AES_ENCRYPT算法:

-- 加密数据

INSERT INTO user_data (username, credit_card) VALUES ('hello', AES_ENCRYPT('1234-5678-9012-3456', 'hello_secret_key'));

那么在做模糊查询的时候就可以这样做:

SELECT * FROM user_data WHERE AES_DECRYPT(credit_card, 'hello_secret_key') like 'Hol%';

这样也就能实现一个模糊查询的效果了,但是这个方案有个缺点,就是无法用到索引,不是因为用like,而是因为我们在字段上用了函数,索引就会失效。

这个方案适合于表中数据量不大,或者查询条件中还有其他查询字段可以走索引的情况。

明文分词

首先有一个比较简单的做法,那就是对明文进行分词,然后分别加密后存储到数据库中,比如liu

这个需要加密的字符串,我们就可以把他拆成,l,li,liu,等这几个字符串,然后分别对他们进行加密,并保存到数据库中。

这样当我们使用,l,li,liu,进行查询的时候,就可以对明文加密后去数据库中匹配了。

这个方案的缺点也比较明显,第一个就是需要冗余很多字段,第二个就是不够灵活,如果我按照

liu来查询的话就不支持。

当然,也有一些改进的方式,比如并不需要增加多个字段,可以把这些需要用于模糊查询的信息都放到同一个字段中,如DECRYPT_NAME,拼接成一个字符串就行了。如71AAFD38484F3160708C6A6D2D5F736B,83B01A578395CE81AEAAC6A4FE70AA9这样就只需要通过这个字段做模糊查询就行了。SQL如下:

SELECT *

FROM hello_test_table WHERE DECRYPT_NAME REGEXP  '71AAFD38484F3160708C6A6D2D5F736B|83B01A578395CE81AEAAC6A4FE70AA94|E90048FB068AA98B7EC751CBD6DC78B7'

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如果数据库加密的,连接数据库的过程会有一些不同: 1. 首先需要使用加密协议连接数据库,如SSL或TLS协议。一般情况下,数据库会提供相应的API来支持加密连接。 2. 连接数据库时需要传入加密证书或密钥,以验证身份并进行加密通信。证书和密钥的生成和管理需要谨慎处理,以确保安全性。 3. 在编写代码时,需要使用支持加密连接的数据库驱动程序,如PyMySQL的ssl参数,来连接加密数据库。 下面是一个使用PyMySQL连接加密的MySQL数据库的示例代码: ```python import os import pymysql.cursors # 加载证书和密钥 ssl_ca = os.path.abspath('ssl/ca.pem') ssl_cert = os.path.abspath('ssl/client-cert.pem') ssl_key = os.path.abspath('ssl/client-key.pem') # 连接数据库 connection = pymysql.connect( host='localhost', user='root', password='password', db='test', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor, ssl={ 'ca': ssl_ca, 'cert': ssl_cert, 'key': ssl_key } ) # 执行SQL语句 try: with connection.cursor() as cursor: sql = "SELECT * FROM `users`" cursor.execute(sql) result = cursor.fetchall() print(result) finally: connection.close() ``` 在这个示例代码中,我们使用了PyMySQL库来连接MySQL数据库,并传入了ssl参数,指定了证书和密钥的位置。在执行SQL语句时,我们直接使用了with语句来获取cursor对象,并执行SQL语句。最后,我们使用connection.close()来关闭数据库连接。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pilgrim786

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值