由于各种原因并不重要,我们在PostgreSQL中以加密或base64编码格式存储文本块。但是,我们希望能够使用PostgreSQL的全文搜索来查找和返回未加密/解码形式的数据与搜索查询匹配。
如何实现这一目标?我看到其他帖子提到在将数据发送到数据库之前构建tsvector值的能力,但我希望在Postgres结尾处有一些可用的东西(至少对于base64文本)。
答案 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,您需要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
编码。