【问题标题】:How do you do a PostgreSQL fulltext search on encoded or encrypted data?您如何对编码或加密数据进行 PostgreSQL 全文搜索?
【发布时间】:2013-03-03 11:25:22
【问题描述】:

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

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

【问题讨论】:

  • 你用什么语言写的?
  • 应用层是Python。

标签: sql postgresql encryption base64


【解决方案1】:

加密值

对于加密值,您不能。即使您创建了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_frombytea解码成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 编码文本所在的编码。您的应用程序负责正确处理.我建议要么将编码存储在第二列中,要么确保您的应用程序始终在应用 base64 编码之前将文本编码为 utf-8

【讨论】:

    猜你喜欢
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 2014-09-10
    • 2023-04-04
    相关资源
    最近更新 更多