如何对编码或加密数据进行PostgreSQL全文搜索?

时间:2013-03-14 21:37:02

标签: sql postgresql encryption base64

由于各种原因并不重要,我们在PostgreSQL中以加密或base64编码格式存储文本块。但是,我们希望能够使用PostgreSQL的全文搜索来查找和返回未加密/解码形式的数据与搜索查询匹配。

如何实现这一目标?我看到其他帖子提到在将数据发送到数据库之前构建tsvector值的能力,但我希望在Postgres结尾处有一些可用的东西(至少对于base64文本)。

1 个答案:

答案 0 :(得分:4)

加密值

对于加密值,您不能。即使您创建了tsvector客户端,tsvector也会包含一种加密文本形式,因此大多数应用程序都无法接受。观察:

regress=> SELECT to_tsvector('my secret password is CandyStrip3r');
               to_tsvector                
------------------------------------------
 'candystrip3r':5 'password':3 'secret':2
(1 row)

...哎呀。如果您创建该值客户端而不是使用to_tsvector并不重要,它仍然会以明文形式显示您的密码。你可以加密tsvector,但是你不能用它来进行全文搜索。

当然,给定加密值:

CREATE EXTENSION pgcrypto;

regress=> SELECT encrypt( convert_to('my s3kritPassw1rd','utf-8'), '\xdeadbeef', 'aes');
                              encrypt                               
--------------------------------------------------------------------
 \x10441717bfc843677d2b76ac357a55ac5566ffe737105332552f98c2338480ff
(1 row)

可以(但不应该)做这样的事情:

regress=> SELECT to_tsvector( convert_from(decrypt('\x10441717bfc843677d2b76ac357a55ac5566ffe737105332552f98c2338480ff', '\xdeadbeef', 'aes'), 'utf-8') );
    to_tsvector     
--------------------
 's3kritpassw1rd':2
(1 row)

...但是如果在代码显示框中滚动后问题就不会立即明显,那么你应该让其他人为你做安全设计; - )

有很多关于如何对加密值执行操作而不对其进行解密的研究,例如将两个加密数字相加以产生使用相同密钥加密的结果,因此执行添加的过程不需要能够解密输入以获得输出。其中一些可能适用于fts - 但它超出了我在该领域的专业水平,并且可能非常低效和/或加密弱。无论如何。

Base64编码值

对于base64,您需要decode base64才能将其输入to_tsvector。由于decode返回bytea并且您知道编码数据是文本,因此您需要使用convert_from将数据库编码中的bytea解码为text,例如:

regress=> SELECT encode(convert_to('some text to search','utf-8'), 'base64');
            encode            
------------------------------
 c29tZSB0ZXh0IHRvIHNlYXJjaA==
(1 row)

regress=> SELECT to_tsvector(convert_from( decode('c29tZSB0ZXh0IHRvIHNlYXJjaA==', 'base64'), getdatabaseencoding() ));
     to_tsvector     
---------------------
 'search':4 'text':2
(1 row)

在这种情况下,我使用数据库编码作为convert_from的输入,但您需要确保使用基础base64编码文本所在的编码。您的应用程序负责为了做到这一点。我建议将编码存储在第二列,或者确保应用总是将文本编码为utf-8,然后再应用base64编码。