cryptography - 使用具有单 block 加密的常量 IV

标签 cryptography aes initialization-vector

我有很多小 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 的足够接近的模拟。

不过,请注意以下几点:

  • 如果您将加密元素存储在数据库中,并且需要在应用程序的整个生命周期内保持唯一性,那么您的 key 是长期存在的。长时间保密 key 可能是一个难题。例如,长期存在的 key 需要某种存储(抵抗重启)。你如何管理死硬盘?你会在充满酸的大锅中摧毁它们吗?
  • 加密确保 secret 性,而不是完整性。在大多数安全模型中,攻击者可能是主动的(即,如果攻击者可以读取数据库,他也可能会写入数据库)。主动攻击会引发一系列问题:例如,如果攻击者交换了您在数据库中的某些 secret ,会发生什么?还是随意改动一些?加密一如既往地是容易的部分(并不是说它真的“容易”,但它比其他工作要容易得多)。
  • 关于cryptography - 使用具有单 block 加密的常量 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5196421/

    相关文章:

    没有IV的php mcrypt加密

    c++ - 文件未完全解密,AES CBC 模式。第一个 block 没有解密。 WCAPI

    C++ XOR加密-解密问题

    javascript - CryptoJS 密码、盐和 iv 不重要吗?

    java - 每条消息都需要 Cipher.init() 吗?

    c# - 如何从 AES 256 加密文件中获取文件类型

    Java AES CTR IV 和计数器

    cryptography - 如何在浏览器中使用Diffie Hellman算法?

    java - 尝试验证数字签名时出现异常

    java - RSA java解密Base64加密String后的垃圾值