为什么 PostgreSQL 的 pgp_sym_encrypt 虽然对相同的输入进行调用却返回不同的输出?

为什么 PostgreSQL 的 pgp_sym_encrypt 虽然对相同的输入进行调用却返回不同的输出?

当我使用相同的明文和密码作为输入执行 PostgreSQLpgp_sym_encrypt命令时,我得到了不同的结果。当使用相同的密码解密这些不同的结果时,我得到了正确的明文。

我想了解为什么加密函数对于具有相同密码的相同纯文本总是给出不同的结果?

纯文本、唯一密钥和会话密钥也存在同样的问题。

我已经在同一列上创建了唯一约束,但得到了不同的加密结果,因此允许多次为同一文本添加新记录。

例子:

pgp_sym_encrypt('12345','key1')

如果我执行上述命令两次,那么我将得到不同的输出,当我解密不同的输出时,我将得到相同的明文。

答案1

OpenPGP 加密

在 OpenPGP 中,消息不直接用密码加密,而是生成一个随机会话密钥作为消息对称加密的密钥。

此会话密钥现在使用密码进行加密。通过应用这种两步方法,可以加密消息一次,但允许使用不同的私钥或密码进行解密,只需添加一次会话密钥的加密副本即可。要更深入地了解 OpenPGP 消息的构造方式,请查看RFC 4880,OpenPGPgpg --list-packets以及加密消息的和的输出pgpdump(它们都打印有关 OpenPGP 数据包的信息)。

此外,每条消息都会填充一些随机字节,这也会导致消息完全不同。最后,加密消息会存储加密时间戳,除非您在同一秒内加密两次,否则时间戳显然会有所不同。

两次加密同一条消息时获得不同的输出可能非常重要:两条消息实际上是同一条消息这一信息通常已经是一个问题。通过使用随机会话密钥和填充,攻击者无法对消息内容做出任何假设,因为他掌握了多条消息。

加密输出的唯一约束

如果需要对消息有唯一约束,请计算消息的加密哈希和(例如,SHA-256)并将其另外存储(并计算哈希和而不是加密消息的唯一约束)。

相关内容