我想问一下有关初始化向量(IV)和对称密码算法密钥使用的最佳实践。
我想接受来自客户端的消息,将其加密并存储在后端。这将在一段时间内完成,并且稍后会收到请求以汇集消息并以可读形式返回它们。
据我所知,在对多个单独的邮件进行加密期间,密钥可以相同。 IV应该随着每次新的加密而改变。但是,这将引起问题,因为每个消息在以后的时间将需要不同的IV进行解密。
我想知道这是否是最好的方法。有什么方法可以避免在每条消息中都存储IV,从而简化了加密/解密的整个过程?
答案 0 :(得分:1)
IV的选择有点复杂,因为确切的要求取决于操作模式。但是,有一些通用规则:
最常见的特定操作模式:
在加密数据库中的数据时,通常不安全地将行ID(或从其派生的值)用作IV。仅在从不更新或删除行的情况下,才使用行ID是安全的,因为否则第二次使用相同的ID存储数据时,它将重复IV。看到两个使用相同密钥和IV加密的不同消息的对手很可能能够解密这两个消息(详细信息取决于模式以及攻击者对消息内容的猜测程度;请注意,即使是较弱的猜测,例如“它可以打印的UTF-8”就足够了。
除非您有很好的理由否则(仅保存每行几个字节并不算是很好的理由),并且密码学家已审查了存储和检索数据的特定方式:>
使用经过身份验证的加密模式,例如GCM,CCM,SIV或Chacha20 + Poly1305。
如果您可以将计数器存储在某个地方,并确保只要您继续使用相同的加密密钥就永远不会重置它,那么每次对邮件进行加密时:
首先增加计数器的原因是,如果该过程被中断,将导致计数器值被跳过,这不是问题。如果第2步没有执行第1步,则将导致重复随机数,这很不好。使用此方案,只要模式允许,就可以将随机数长度减少几个字节,只要该长度足够大,就可以加密任何数量的消息。
如果没有这样的计数器,请使用最大随机数长度并生成一个随机计数器。使用最大随机数长度的原因是由于birthday paradox,当消息数接近2 n时,预期会随机重复 n 位随机数 / 2 。
无论哪种情况,都需要将随机数存储在行中。
¹假设一切都正确实现,例如需要使用适合于密码学的随机生成器来生成随机值。
²,只要未以取决于键的方式选择它即可。