用于对称加密的密码磨损

2020-12-24 21:25:09

当我们看着非常疲惫的一年的日落时,我认为谈论加密损耗是适当的。

这是您使用同一密钥加密大量数据的阈值,因此您可能应先切换到新密钥,然后再进行加密。否则,您可能会让有能力观察您所有加密数据的人进行有趣的攻击,从而破坏您加密数据的安全性。

阈值的确切值取决于您对数据加密的精确程度(n.b. AEAD模式,分组密码+密码模式等,由于其组成而各自具有不同的损耗阈值)。

让我们看一下更流行的对称加密方法的损耗极限,然后自己计算这些极限。

AES-GCM是一种将AES-CTR与身份验证器(称为GMAC)结合在一起的结构,其现时消耗看起来像这样:

计算H(在GHASH中用于使用同一密钥加密的所有消息,无论是否随机数):

加密的每个数据块都使用J0 +块计数器(从1开始)作为CTR随机数。

AES-GCM是一种算法,可以轻松地分别计算每封邮件(对于给定的随机数和密钥)以及密钥下的所有邮件的安全限制。

在最简单的情况下(一次是96位),最终会消耗以下随机数:

从这里可以很容易地看到,您可以加密从00000002到FFFFFFFF的块,而不会溢出和创建随机数重用。这意味着每个(密钥,随机数)都可以用于加密单个消息,最多加密基础密文块。

由于AES的块大小为16个字节,因此这意味着单个AES-GCM(密钥,随机数)对的最大长度为字节(或68,719,476,480字节)。这大约是68 GB或64 GiB。

由于随机数是经过哈希处理的,因此当随机数不是96位时,分析起来会有些麻烦。

这种哈希行为的缺点是,两个不同的随机数可能会产生AES-CTR输出的重叠范围,这使得安全性分析非常困难。

但是,由于网络观察者不知道H的值,因此也隐藏了此哈希输出。如果没有某种可靠的方法来检测隐藏块计数器的重叠范围,则无法利用此方法。

(如果您想过着危险的生活并激发密码分析研究,请将96位和非96位随机数与具有相同功能的系统中的相同密钥混合使用。)

既然我们已经确定了一条消息的最大长度,那么在给定的AES-GCM密钥下可以安全地加密多少条消息完全取决于您选择的随机数。

如果您有一个可靠的计数器(保证永不重复),并将其从0开始,则理论上可以安全地加密消息。万岁!

您可能没有可靠的计数器,尤其是在现实环境中(分布式系统,多线程应用程序,可能已快照和还原的虚拟机等)。

另外(由于采用了2adic的权宜之计),您无法使用AES安全地加密多个块,因为密钥流块(作为块密码的输出)无法重复。

大多数不能保证唯一递增的随机数的系统都只是使用加密安全的随机数生成器来生成随机数。这是一个好主意,但是无论您的随机数生成器的质量如何,随机函数都会产生离散概率的碰撞。

如果有可能的值,则应该在(或)采样后发生一次碰撞(概率为50%)。这称为生日界限。

但是,对于大多数系统而言,随机数重用的50%并不是完全合适的安全阈值(尤其是因为随机数重用会导致AES-GCM容易受到主动攻击者的攻击)。相对于每2倍中的1倍,每40亿中有1倍的安全余量可以更好地防止通过随机重用随机数。幸运的是,您可以轻松计算生日碰撞的离散概率。

如果要在碰撞概率超过之后(对于0到之间的随机随机数)重新输入密钥,只需在消息后重新输入密钥。

消息的最大数量(连续的随机数):(但您可能在现实世界中没有这种奢侈的感觉)

ChaCha20-Poly1305的IETF版本使用96位随机数和32位内部计数器。 AES-GCM进行了类似的分析,但有一些值得注意的例外。

对于初学者,一次性Poly1305密钥是从给定(随机数,密钥)对的ChaCha20密钥流输出(块0)的前32个字节派生的。没有等效于AES-GCM的H参数,该参数对于每个密钥都是静态的。 (ChaCha20加密从块1开始。)

此外,ChaCha20的每个块均为512位,与AES的128位不同。因此,此处的消息限制更为宽容。

由于块大小为512位(或64字节),并且Poly1305密钥派生仅占用一个块,因此我们可以计算出消息长度限制为或274,877,906,880字节-每对(即刻,密钥)对的长度接近256 GiB。

处理AES-GCM的处理96位随机数的规则相同,因此我们可以将其继续使用。

消息的最大数量(连续的随机数):(但您可能在现实世界中没有这种奢侈的感觉)

XChaCha20-Poly1305是XSalsa20-Poly1305(用于libsodium中)和IETF的ChaCha20-Poly1305结构的变体。它具有192位随机数和32位内部计数器。

通过在随机数的前128位上使用密钥的HChaCha20实例化XChaCha20-Poly1305,以生成一个子密钥,该子密钥可通过上述ChaCha20-Poly1305与其余的随机数位一起使用。

这不会更改邮件的最大长度,但是会更改可以安全加密的邮件数量(因为实际上您在使用最多的密钥)。

因此,即使您设法重复最后的ChaCha20-Poly1305随机数,只要总的随机数不同,每个加密都将使用不同的密钥执行(这要归功于HChaCha20密钥的派生;有关详细信息,请参见XSalsa20文件和IETF RFC草案) )。

消息的最大数量(连续的随机数):(但您可能在现实世界中没有这种奢侈的感觉)

比较非AEAD结构和CBC(Cipher Block Chaining)等分组密码模式很诱人,但它们是完全不同的怪物。

AEAD密码在消息长度限制和消息数量限制之间有清晰的界限

每次使用AES-CBC加密数据块时,都会消耗一个通用存储桶,该存储桶会影响在该密钥下加密更多消息的生日安全性。 (与具有较长随机数的AES-GCM不同,AES-CBC的IV是公开的。)

这是对AES-CBC的操作要求的补充(明文填充,永远不会重复且必须不可预测的初始化矢量,独立的消息身份验证,因为CBC无法提供完整性并且容易受到密文攻击。)

因此,大多数密码学家甚至都不会像讨论AES-GCM那样费心计算AES-CBC的安全极限。他们这样做是对的!

如果您发现自己使用的是AES-CBC(或AES-CTR),则最好在密文上执行单独的HMAC-SHA256(并在解密之前使用安全比较功能验证此HMAC)。此外,您应该考虑使用扩展的随机数结构来拆分一次性加密和身份验证密钥。

但是,为了完整起见,让我们找出我们的实际限制。

无论您是否需要整个块,CBC都会在整个明文块上运行。

加密时,将前一个块的输出与当前块混合(使用XOR),然后使用块密码进行加密。对于第一个块,使用IV代替“上一个”块。 (因此,它的要求是不可重复且不可预测的。)

这意味着您可以将(IV xor PlaintextBlock)和(PB n xor PB n + 1)非正式地建模为伪随机函数,然后再使用分组密码进行加密。

如果这些词对您没有任何意义,请按以下步骤操作:您可以使用上面有关生日限制的讨论来计算使用单个AES密钥加密的块总数的安全上限(假设IV是由安全密钥生成的)随机来源)。

如果您认为发生冲突的可能性为50%,则应该在对块进行加密之后重新输入密钥。

如果您的安全裕度接近40亿分之一(与AES-GCM一样),则需要在块之后重新输入密钥。

如果您的纯文本始终是128位(或16字节)的偶数倍,则最多允许使用纯文本字节。如果您使用的是PKCS#7填充,请记住,这将在每封邮件中包含一个完整的填充块,因此您的安全裕度将更快地耗尽(取决于您加密的单个邮件数量,以及因此而决定的填充块数量)需要)。

在另一种极端情况下(1字节纯文本),在重新键入密钥之前,您只能查看加密的字节。

因此,为了保持在AES-CBC的安全范围内,应在对块(包括填充)进行加密之后重新输入密钥。

请记住:单字节块仍然是大约281 TiB的数据(包括填充)。在高端,15字节的块(保留1字节的填充以保留在一个块内)的时钟频率约为4.22 PiB。

如果您的纯文本始终为16个字节(因此需要额外的16个字节的填充),则会发生局部极值。更少,并且填充适合一个块。再也没有了,数据:填充率开始占主导地位。

因此,使用填充的最坏情况是您将上述安全限制用于块计数,并将其减少一半。将数字减半意味着将指数减少1。

但这仍然不能消除差异。块的范围可以是从纯文本的字节到字节。在这种情况下,我们必须假设最坏的情况(n.b.取最保守的值)。

在单个密钥下以随机随机数安全加密的最大数据量:字节(约141 TiB)

与AES-CBC相比,AES-GCM在相同威胁配置文件下,使用相同密钥可获得的使用量大约是您的一百万倍。 ChaCha20-Poly1305和XChaCha20-Poly1305在同一密钥下提供了更大的加密数据余量。 后者甚至可以安全地用于使用单个密钥加密任意数量的数据,而不必担心实际达到生日的限制(尽管消息长度仍然受到一定限制)。 我知道该博客帖子可能只是一个比较表和一些脚注(甚至是IETF RFC草案),但我认为解释这些值如何从密码结构中得出来会更有趣。