使用 pgcrypto 扩展对加密数据的 postgresql 主键约束

postgresql primary key constraint on encrypted data using pgcrypto extension

我正在使用 PostgreSQL 8.4,并使用 pgcrypto 扩展中的 pgp_sym_encrypt 函数在插入时加密数据。所以我的插入查询看起来像:

insert into myTable (
                     column1
                    ,column2
                     ) 
values (
        pgp_sym_encrypt('value1','key')
       ,pgp_sym_encrypt('value1','key')
       );

我在 table 中对 column1 应用了主键约束,但该约束并不总是检测到插入一个已经存在的值,因为对于相同的解密值,加密数据并不总是相同的。

问题:

我如何应用此约束,以便它检查解密数据是否匹配并且在这种情况下不允许插入?

如果您希望强制执行唯一性,您最好的选择是对您的信息进行哈希处理并将该哈希存储在具有唯一索引的单独列中,我经常使用摘要来检查较长文本的唯一性,纯粹是因为 space 它有要求,但是由于哈希的不可逆性,其余部分应该是不可发现的。 首先你需要一个列:

alter table myTable add column column3 bytea unique;

然后您的插入只需包含第 3 列

insert into myTable(
column1
,column2
,column3
)
values (
pgp_sym_encrypt('value1','key')
,pgp_sym_encrypt('value1','key')
,digest('value1', 'sha256')
)

sha256 应该很容易混淆数据,以至于以这种形式存储的任何内容都永远不会被成功破译,并且在二进制列中只需要 32 个字节,加上索引。 作为记录,不同哈希值的数据长度为:

select length(digest('your message goes here', 'sha1'));
-- 20
select length(digest('your message goes here', 'sha256'));
-- 32
select length(digest('your message goes here', 'sha512'));
-- 64

最后,您是用 'key' 加密了两次 'value1' 还是它们是两个独立的信息?我猜测它们应该是两个不同的数据列,如果是这样,并且您需要两者的唯一性,您当然需要创建一个进一步的列并对其进行哈希处理。