初始化向量-最佳做法(对称加密)

时间:2019-02-01 23:02:10

标签: cryptography aes encryption-symmetric

我想问一下有关初始化向量(IV)和对称密码算法密钥使用的最佳实践。

我想接受来自客户端的消息,将其加密并存储在后端。这将在一段时间内完成,并且稍后会收到请求以汇集消息并以可读形式返回它们。

据我所知,在对多个单独的邮件进行加密期间,密钥可以相同。 IV应该随着每次新的加密而改变。但是,这将引起问题,因为每个消息在以后的时间将需要不同的IV进行解密。

我想知道这是否是最好的方法。有什么方法可以避免在每条消息中都存储IV,从而简化了加密/解密的整个过程?

1 个答案:

答案 0 :(得分:1)

IV的选择有点复杂,因为确切的要求取决于操作模式。但是,有一些通用规则:

  • 使用随机IV不会出错,除非在允许这种情况的模式下使用较短的IV。
  • 切勿使用相同的IV和相同的键。
  • 如果您只用给定的密钥加密一条消息,那么IV的选择就无所谓²。
  • 独立于要加密的数据选择IV。
  • 请勿使用ECB。

最常见的特定操作模式:

    CBC要求IV随机生成。请勿将计数器用作CBC的IV。此外,如果您要加密某些数据,其中包含从第三方收到的部分,则在完全接收到数据之前,不要显示IV。
  • CTR使用IV作为计数器的初始值,它对每个块(而不是对每个消息)递增 ,并且每个块的计数器值必须唯一。对于所有现代对称密码(包括AES,无论密钥大小),一个块均为16字节。因此,对于点击率,如果您以0作为IV加密3块消息(33到48个字节),则下一条消息必须以IV = 3(或更大)而不是IV = 1开头。
  • Chacha20,GCM,CCM,SIV等现代模式将 nonce 用作其IV。当一个模式被描述为使用随机数而不是IV时,这意味着唯一的要求是IV绝不能使用相同的密钥重用。不一定是随机的。

在加密数据库中的数据时,通常不安全地将行ID(或从其派生的值)用作IV。仅在从不更新或删除行的情况下,才使用行ID是安全的,因为否则第二次使用相同的ID存储数据时,它将重复IV。看到两个使用相同密钥和IV加密的不同消息的对手很可能能够解密这两个消息(详细信息取决于模式以及攻击者对消息内容的猜测程度;请注意,即使是较弱的猜测,例如“它可以打印的UTF-8”就足够了。

除非您有很好的理由否则(仅保存每行几个字节并不算是很好的理由),并且密码学家已审查了存储和检索数据的特定方式:

  • 使用经过身份验证的加密模式,例如GCM,CCM,SIV或Chacha20 + Poly1305。

  • 如果您可以将计数器存储在某个地方,并确保只要您继续使用相同的加密密钥就永远不会重置它,那么每次对邮件进行加密时:

    1. 增加计数器。
    2. 将计数器的新值用作经过身份验证的加密的随机数。

    首先增加计数器的原因是,如果该过程被中断,将导致计数器值被跳过,这不是问题。如果第2步没有执行第1步,则将导致重复随机数,这很不好。使用此方案,只要模式允许,就可以将随机数长度减少几个字节,只要该长度足够大,就可以加密任何数量的消息。

  • 如果没有这样的计数器,请使用最大随机数长度并生成一个随机计数器。使用最大随机数长度的原因是由于birthday paradox,当消息数接近2 n时,预期会随机重复 n 位随机数 / 2

  • 无论哪种情况,都需要将随机数存储在行中。

¹假设一切都正确实现,例如需要使用适合于密码学的随机生成器来生成随机值。
²,只要未以取决于键的方式选择它即可。