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

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

我在表中对Cyrn1应用主键约束,但是约束不会总是检测插入已经存在的值,因为加密的数据对于相同的解密值不总是相同的。
问题:
如何应用此约束,以便它检查解密数据是否匹配,并且在这种情况下不允许插入?

最佳答案

如果您希望强制实现唯一性,最好的方法是散列您的信息,并将散列存储在具有唯一索引的单独列中,我经常使用摘要检查较长文本的唯一性,这纯粹是因为它具有较小的空间要求,但是由于散列的不可逆性质,其余部分应该是不可发现的。
首先需要一个列:

alter table myTable add column column3 bytea unique;

那么你的插入部分只包括第三列
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”加密两次,还是它们是两个独立的信息?我猜它们应该是两个不同的数据列,如果是这样的话,你需要在这两个数据列上都是唯一的,当然你还需要创建一个列并散列它。

09-07 15:07
查看更多