我有很多小 secret 要加密存储在数据库中。数据库客户端将拥有 key ,数据库服务器不会处理加密和解密。我所有的 secret 都是 16 字节或更少,这意味着使用 AES 时只有一个块。我正在使用一个常量 IV(和 key )来使加密具有确定性,我进行确定性加密的原因是能够使用密文轻松查询数据库并确保相同的 secret 不会存储两次(通过使列 UNIQUE )。据我所知,只要 key 是 secret 的,这样做应该没有问题。但我想确定:我是对还是错?如果我错了,可以进行哪些攻击?
顺便说一句:哈希在这里毫无用处,因为可能的明文数量相对较少。使用散列获取原始明文将是微不足道的。
最佳答案
对于长度为 n 位的消息,理想的密码是 2n 个 n 位序列的排列,在 2n!这样的排列。 “键”是对选择哪个排列的描述。
安全块密码应该与理想密码无法区分,n 是块大小。对于 AES,n=128(即 16 字节)。 AES 应该是一种安全的分组密码。
如果您所有的 secret 长度恰好为 16 个字节(或小于 16 个字节,使用一些填充约定明确将它们扩展到 16 个字节),那么理想的密码就是您想要的,而 AES“本身”应该没问题。对于想要应用填充和处理任意长流的常见 AES 实现,您可以通过要求 ECB 模式或具有全零 IV 的 CBC 模式来获得单块加密。
所有关于 IV 的问题,以及为什么首先需要 CBC 等链接模式,都来自多块消息。 AES 加密 16 字节的消息(不多也不少):链接模式是为更长的消息模拟理想的密码。如果在您的应用程序中,所有消息的长度恰好为 16 个字节(或者更短,但您添加了填充),那么您只需要“原始”AES;固定的 IV 是对原始 AES 的足够接近的模拟。
不过,请注意以下几点:
关于cryptography - 使用具有单 block 加密的常量 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5196421/