PostgreSql:如何使用加密列进行查询

PostgreSql:如何使用加密列进行查询,postgresql,postgresql-9.6,pgcrypto,Postgresql,Postgresql 9.6,Pgcrypto,场景: 我创建了一个表: 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

场景:

我创建了一个表:

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);
问题: 现在,我尝试使用加密昵称列从表中获取记录,如中所述:

我没有得到任何回报。注意,我必须将
昵称
转换为
varchar
。即使我将列类型更改为bytea,我仍然一无所获。请注意,我的对称密钥实际上是相同的:
AES\u-key
。我没有在任何地方生成它。我需要改变长度吗


我的PostGreSql版本是9.6。

您的加密数据列应定义为
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%')
);

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


似乎将s2k模式设置为0会产生可重复的加密,但从实验上看并非如此。也许IV仍然是随机的?

注意:不要加密数据库中的密码,而是对它们进行散列。密码永远不能被解密。这只是一个例子。在我真正的项目中,我正在对密码进行哈希运算。但有些列在数据库中时需要加密,在应用程序检索时需要解密,因此在这种情况下需要双向加密。我将更改示例,使其不使用密码列。它成功了。然而,在另一个单独的not上,我端不识别较低的关键字。PostgreSql 9.6不支持它吗?另外,您是否知道该查询是否会首先解密表中的所有记录,然后比较给定的文本?或者它会一个接一个地解密每个记录并单独比较吗?“LOWER”可以删除,因为我刚刚添加了它。我不确定执行周期。
SELECT 
    PGP_SYM_DECRYPT(nickname::bytea, 'AES_KEY') as name,
FROM knights WHERE ( 
    LOWER(PGP_SYM_DECRYPT(nickname::bytea, 'AES_KEY')
    LIKE LOWER('%Rigid%')
);