【问题标题】:PostgreSql: How to query using encrypted columnsPostgreSql:如何使用加密列进行查询
【发布时间】:2020-06-09 06:03:57
【问题描述】:

场景:

我已经创建了一个表:

Create table knights(age integer, nickname varchar(255));

然后我插入了几条记录,并使用 pgcrypto 加密了昵称列数据:

insert into knights values(21, PGP_SYM_ENCRYPT('ShiningArmor','AES_KEY')::varchar);
insert into knights values(32, PGP_SYM_ENCRYPT('Rigid','AES_KEY')::varchar);

问题: 现在我尝试按照this answer 中的建议使用加密的昵称列从表中获取记录:

SELECT * FROM knights WHERE nickname = pgp_sym_encrypt('Rigid', 'AES_KEY')::varchar;

我一无所获。请注意,我必须将 nickname 转换为 varchar。即使我将列类型更改为 bytea,我仍然一无所获。请注意,我的对称密钥实际上是相同的:AES_KEY。我没有在任何地方生成它。我需要更改长度吗?

我的 PostGreSql 版本是 9.6。

【问题讨论】:

  • 注意:不要对数据库中的密码进行加密,对它们进行哈希处理。密码永远不可解密。
  • 这只是一个例子。在我的真实项目中,我正在对密码进行哈希处理。但是有一些列需要在数据库中加密并在应用程序检索它们时解密,因此在这种情况下需要 2 路加密。我将更改示例以不使用密码列。

标签: postgresql postgresql-9.6 pgcrypto


【解决方案1】:

您的加密数据列应定义为bytea

当你阅读查询时应该如下,

SELECT 
    PGP_SYM_DECRYPT(nickname::bytea, 'AES_KEY') as name,
FROM knights WHERE ( 
    LOWER(PGP_SYM_DECRYPT(nickname::bytea, 'AES_KEY')
    LIKE LOWER('%Rigid%')
);

【讨论】:

  • 成功了。但是,在单独的情况下,我最终无法识别较低的关键字。 PostgreSql 9.6 不支持吗?
  • 另外,你知道这个查询是否会先解密表中的所有记录,然后比较给定的文本?还是将每条记录一一解密,分别比较?
  • 'LOWER' 可以删除,因为我刚刚添加了它。我不确定执行周期。
【解决方案2】:

pgp_sym_encrypt 使用盐,因此每次使用相同密码加密相同值时不会得到相同的答案。正如公认的答案所暗示的,答案是使用解密而不是加密进行测试。

似乎将 s2k-mode 设置为 0 应该会产生可重复的加密,但在实验上它不会。也许 IV 仍然是随机的?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2020-12-16
    相关资源
    最近更新 更多