如何选择AES加密模式(CBC ECB CTR OCB CFB)?

608
在哪些情况下更喜欢它们?我想看到各种模式的评估标准列表,或许还要讨论每个标准的适用性。例如,我认为加密和解密的“代码大小”是一个标准,这对于微代码嵌入式系统(如802.11网络适配器)非常重要。如果实现CBC所需的代码比实现CTR所需的代码小得多(我不知道这是否正确,仅作为示例),那么我可以理解为什么选择较小的代码模式。但是,如果我正在编写运行在服务器上的应用程序,并且我使用的AES库已经实现了CBC和CTR,那么这个标准就无关紧要了。你明白我所说的“评估标准列表和每个标准的适用性”吗? 这与编程无关,但与算法相关。
9个回答

537

请认真考虑,如果无法实现自己的加密,请三思而后行

事实上,丑陋的真相是,如果您正在问这个问题,那么您可能无法设计和实现一个安全的系统。

让我解释一下我的观点:假设您正在构建一个Web应用程序并需要存储一些会话数据。您可以为每个用户分配一个会话ID,并将会话数据存储在服务器上的哈希映射中,将会话ID映射到会话数据。但是,这样您就必须处理服务器上的这种烦人状态,如果在某个时候您需要多个服务器,情况将变得混乱。因此,您想到了将会话数据存储在客户端的Cookie中。当然,您会对其进行加密,以便用户无法读取和操纵数据。那么,您应该使用哪种模式?来到这里,您阅读了最佳答案(抱歉,我要单独提出myforwik)。第一个涵盖的ECB不适合您,您需要加密多个块,下一个CBC听起来不错,您不需要CTR的并行性,也不需要随机访问,因此不需要XTS和专利问题,因此不使用OCB。使用您的加密库,您意识到您需要一些填充,因为您只能加密块大小的倍数。您选择PKCS7,因为它在某些严格的密码学标准中定义。在某处读到,如果使用随机IV和安全块密码,则CBC是可证明安全的,因此即使您将敏感数据存储在客户端上,您也可以放心。
多年之后,当您的服务已经发展到相当规模时,一名IT安全专家通过负责任漏洞披露与您联系。她告诉您,由于您的代码在填充出现问题时会产生错误页面,因此她可以使用填充攻击来解密所有的cookie。 这不是一个假设性的场景:微软的ASP.NET曾经存在这个严重缺陷,直到几年前才得以解决。 问题在于,涉及加密学有很多陷阱,很容易建立一个对于外行人看起来很安全,但对于知识渊博的攻击者却毫不费力的系统。

如果需要加密数据应该怎么办

使用TLS进行实时连接(确保检查证书的主机名和发行人链)。如果无法使用TLS,请寻找系统提供的最高级别API以完成任务,并确保您理解它所提供的保证,更重要的是,它不提供什么保证。对于上面的示例,像Play这样的框架提供客户端存储设施,但它不会在一段时间后使存储的数据无效,如果更改了客户端状态,则攻击者可以恢复以前的状态而不被注意到。
如果没有高级抽象可用,使用高级加密库。一个著名的例子是NaCl,而具有多种语言绑定的便携式实现是Sodium。使用这样的库,您不必担心加密模式等问题,但您必须比使用更高级别的抽象(例如从未重复使用nonce)更加小心使用细节。对于自定义协议构建(比如说你想要类似TLS的东西,但不在TCP或UDP上),有像Noise这样的框架和相关实现可以为您完成大部分繁重的工作,但它们的灵活性也意味着如果您不深入了解所有组件的功能,则存在很大的错误空间。
如果由于某些原因你无法使用高级加密库,例如因为你需要以特定方式与现有系统交互,那么唯一的办法就是彻底学习。我建议阅读Ferguson、Kohno和Schneier的密码工程。请不要自欺欺人地认为你可以在没有必要的背景知识的情况下构建一个安全的系统。密码学非常微妙,几乎不可能测试一个系统的安全性。

模式比较

仅加密:

  • 需要填充的加密模式: 像示例中一样,填充通常是危险的,因为它打开了填充预言攻击的可能性。最简单的防御方法是在解密之前对每条消息进行身份验证。请参见下文。
    • ECB 独立加密每个数据块,相同的明文块将导致相同的密文块。查看 ECB Wikipedia page 上的 ECB 加密 Tux 图像,以了解这是一个严重的问题的原因。我不知道任何可以接受 ECB 的用例。
    • CBC 具有 IV,因此每次加密消息时都需要随机数,更改消息的一部分需要重新加密更改后的所有内容,一个密文块中的传输错误完全破坏了明文并更改了下一个块的解密,解密可以并行化/加密不能,明文在某种程度上是可塑的 - this can be a problem
  • 流密码模式:这些模式生成伪随机数据流,可能与明文依赖或不依赖。与流密码一般情况下一样,生成的伪随机流与明文异或以生成密文。由于您可以使用任意多位随机流,因此根本不需要填充。这种简单性的缺点是加密是完全 malleable 的,这意味着攻击者可以按任意方式更改解密,例如对于明文 p1、密文 c1 和伪随机流 r,攻击者可以选择差异 d,使得密文 c2=c1⊕d 的解密为 p2 = p1⊕d,因为 p2 = c2⊕r = (c1 ⊕ d) ⊕ r = d ⊕ (c1 ⊕ r)。同样的伪随机流永远不能重复使用,因为对于两个密文 c1=p1⊕r 和 c2=p2⊕r,攻击者可以计算两个明文的异或值 c1⊕c2=p1⊕r⊕p2⊕r=p1⊕p2。这也意味着如果原始消息可能已被攻击者获取,则更改消息需要完全重新加密。以下所有流密码模式仅需要块密码的加密操作,因此取决于密码,这可能会在极度受限制的环境中节省一些(硅或机器码)空间。
    • CTR 很简单,它创建一个与明文无关的伪随机流,通过从不同的 nonce/IV 计数并乘以最大消息长度来避免重叠,从而获得不同的伪随机流,使用 nonce 可以进行消息加密而无需每条消息都有随机数,解密和加密可以并行完成,传输错误仅影响错误位而不会影响更多内容
    • OFB 也创建了与明文无关的伪随机流,通过为每条消息启动不同的 nonce 或随机 IV 来获得不同的伪随机流,加密和解密都不能并行化,与 CTR 一样,使用 nonce 可以进行消息加密而无需每条消息都有随机数,与 CTR 一样,传输错误只影响错误位而不会影响更多内容
    • CFB 的伪随机流取决于明文,每条消息需要不同的 nonce 或随

      认证加密:

      为了防止填充预言攻击和密文更改,可以在密文上计算消息认证码(MAC),只有在未被篡改的情况下才解密它。这称为“加密然后认证”,应优先考虑使用此方法。除非极少数情况下,真实性与保密性同样重要(后者是加密的目的)。带关联数据的认证加密方案(AEAD)将加密和身份验证两个过程合并为一个块密码模式,并在过程中生成身份验证标签。在大多数情况下,这会导致速度提高。

      • CCM是CTR模式和CBC-MAC的简单组合。每个块使用两次分组密码加密,速度非常慢。
      • OCB更快,但受专利限制。对于自由软件或非军事软件,专利持有人已经授予了免费许可证。
      • GCM是CTR模式和GHASH的复杂组合,GHASH是一个具有2^128个元素的伽罗瓦域上的MAC。它在重要的网络标准(如TLS 1.2)中的广泛使用反映在Intel引入了一项特殊指令来加速GHASH的计算。

      推荐:

      考虑到身份验证的重要性,我建议对于大多数用例(除了磁盘加密目的),使用以下两种分组密码模式:如果数据通过非对称签名进行身份验证,则使用CBC,否则使用GCM。


309
如果你需要问这个问题,那么你可能对密码学的了解还不足以实现一个安全的系统。——你说得没错,但你应该知道,提问是人们学习的方式。所以或许可以放松一下。 - Robert MacLean
92
@RobertMacLean 说得没错,但与IT领域的许多其他领域不同的是,试错方法并不能确保安全性。而在网页设计、应用程序可扩展性等方面,您可以积极检查要求,测试安全方面的内容则难以做到或几乎不可能。不幸的是,这是一个很少有人教授的教训。大多数资源告诉您密码学的工作原理,而没有让您意识到它在实践中失败的无数方式。唯一的出路就是要对该主题了解得非常透彻。这就是本篇文章的寓意。 - Perseids
12
要么花足够的时间深入了解密码学,要么尽可能避免使用它并使用强大的抽象。在学习密码学破解的主题下,第一段比模式描述更相关。 - Perseids
59
减一:起始标题有误,应该写成“如果你正在问这个问题,那么你正在走向正确的方向,继续努力,你会取得成功!” - Henrik
12
@FerminSilva说的没错,但是争论中的另一个方面是,使用经过验证的解决方案通常比复制粘贴加密代码更容易。例如,当你只想通过智能手机应用程序与服务器通信时,建立一个带有Let's Encrypt TLS证书的Apache反向代理,并在应用程序中到处写上https://your.server要简单得多,而不是发明某些密钥交换协议并让两端的加密库顺利地协作。 - Perseids
显示剩余27条评论

386
  • 如果使用相同密钥加密多个数据块,则不应使用ECB。

  • CBC、OFB和CFB类似,但OFB/CFB更好,因为只需要加密而不需要解密,这可以节省代码空间。

  • 如果想要良好的并行性(即速度),则应使用CTR,而不是CBC/OFB/CFB。

  • 如果要编码随机可访问的数据(如硬盘或RAM),则XTS模式是最常见的。

  • OCB是迄今为止最好的模式,因为它允许在单次传递中进行加密和身份验证。但是,在美国有专利。

你真正需要知道的是,除非只加密1个数据块,否则不要使用ECB。如果要加密随机访问的数据而不是流,则应使用XTS。

  • 每次加密时,您应该始终使用唯一的IV,并且它们应该是随机的。如果您无法保证它们是随机的,请使用OCB,因为它只需要一个nonce而不是IV,而且有明显的区别。如果人们可以猜测下一个nonce,则不会降低安全性,但IV可能会导致这个问题。

70
CBC、OFB和CFB这三种加密模式并不完全相同。 - Jonathan Leffler
23
由于CTR模式可以将消息分成多个块,每个块有一个计数器值范围与之关联,并独立地加密(或解密)每个块,因此它易于并行化。相比之下,CFB模式则需要前一块的输出作为下一块的输入之一,因此它严格是顺序执行的,无法进行并行化处理。其他提到的模式也类似。 - Jonathan Leffler
10
即使您只加密一个数据块,如果您将使用相同的密钥对该数据块进行多次加密(甚至可能是多次),也不应使用ECB模式。 - yfeldblum
27
为什么一个回答说“CBC、OFB和CFB是相同的”没有一个downvote(反对)?请问您如何将这个回答翻译成中文?请注意不要改变原意。 - Michael Mrozek
33
GCM与OCB非常相似(性能和其他属性),但没有任何专利限制,因此是最佳选择。唯一的缺点是它的实现非常复杂 - 但如果您使用库,则不必担心这一点。 - ntoskrnl
显示剩余7条评论

57
2011年,Phil Rogaway进行了正式分析(这里)。在第1.6节中,他总结如下(加粗表示我的强调):如果你着急的话,他的建议是使用CTR模式,但我建议您先阅读下面关于消息完整性与加密的段落。
请注意,大多数模式需要随机IV(初始化向量),这意味着应该使用具有密码学安全性的方法生成非预测的IV。然而,某些模式仅需要“nonce”(只需求不重复即可,无需保证不可预测),因此依赖nonce的设计比不依赖nonce的设计更少出错(相信我,我见过许多未经适当IV选择实现的CBC案例)。因此,当Rogaway说“IV为nonce时无法实现保密性”等话语时,如果您选择密码学安全的IV(不可预测),那么没问题。但如果您没有,那么就会丧失良好的安全性质。对于所有这些模式,永远不要重复使用IV
此外,重要的是要理解消息完整性和加密之间的区别。加密隐藏数据,但攻击者可能能够修改加密数据,如果您不检查消息完整性,软件可能会接受结果。开发人员会说“但修改后的数据在解密后将变成垃圾”,但好的安全工程师将找到垃圾导致软件产生不良行为的概率,然后将该分析转化为实际攻击。我见过很多情况,其中使用了加密但需要消息完整性而不是加密。了解您需要的内容。
我应该说,尽管GCM具有加密和消息完整性,但它是一个非常脆弱的设计:如果重复使用IV,则会暴露密钥。其他设计则更加健壮,因此我个人不敢推荐GCM,因为我在实践中看到了大量糟糕的加密代码。
如果您需要消息完整性和加密,则可以组合两种算法:通常我们看到CBC与HMAC结合使用,但没有理由绑定自己于CBC。重要的是要知道先加密,再对加密内容进行MAC计算(这里),而不是相反。此外,IV需要是MAC计算的一部分。
我不知道IP问题。
以下是Phil Rogaway教授提供的有关块密码模式的加密(但不具备消息完整性)模式的列表:

ECB: 一种块密码模式,逐个加密长度为n比特的消息块。但安全性较弱,该方法会泄露块之间的等性特征,从而影响整体安全性。它具有重要的遗产价值,并且可以用作其他方案的基础构件,但是必须小心使用;不应将ECB视为“通用”的保密模式

CBC: 一种IV(初始化向量)加密方案,该模式作为概率加密方案是安全的,可以实现与随机位无法区分的安全性,前提是使用随机IV。如果IV仅作为nonce,则不能实现保密性,如果将其作为方案使用的相同密钥下的nonce进行加密,则也不能满足保密性,因为标准错误地建议这样做。密文易受篡改。没有选择密文攻击(CCA)安全性。许多填充方法存在正确填充Oracle的情况下,保密性将被放弃。加密效率低下,因为其本质上是串行的。广泛使用的此模式的仅限于隐私保护的安全属性导致经常被滥用。可用作CBC-MAC算法的构建块。我无法识别出与CTR模式相比的重要优势。

CFB: 一种IV加密方案,该模式作为概率加密方案是安全的,可以实现与随机位无法区分的安全性,前提是使用随机IV。如果IV是可预测的,则不能实现保密性,同样地,如果它由方案使用的相同密钥下的nonce进行加密,则也不能满足保密性,因为标准错误地建议这样做。密文易受篡改。没有CCA安全性。加密效率低下,因为其本质上是串行的。该方案取决于参数s,1≤s≤n,通常情况下,s=1或s=8。需要一个块密码调用才能处理只有s位的数据,因此效率低下。该模式具有有趣的“自同步”属性;任何数量的s位字符的插入或删除仅会暂时破坏正确解密。

OFB: 一种IV加密方案,该模式作为概率加密方案是安全的,可以实现与随机位无法区分的安全性,前提是使用随机IV。如果IV是nonce,则不能实现保密性,尽管固定的IV序列(例如计数器)可以正常工作。密文易受篡改。没有CCA安全性。加密和解密效率低,因为其本质上是串行的。原生加密任何位长的字符串(不需要填充)。我无法识别出与CTR模式相比的重要优势。

CTR: 一个基于IV的加密方案,假设nonce IV即可实现与随机位无法区分的安全性。作为安全的nonce-based方案,该模式也可以作为概率加密方案,使用随机IV。如果在加密或解密中重复使用nonce则会完全破坏隐私。该模式的可并行性通常使其比其他保密模式更快,在某些情况下快得多。是验证加密方案的重要构建块。总体而言,通常是实现仅隐私加密的最佳和最现代的方法。

XTS: 一种基于IV的加密方案,该模式通过对每个n位块应用一个可调谐的块密码(作为强PRP安全)来运作。对于长度不可被n整除的消息,最后两个块会被特殊处理。该模式唯一允许的用途是加密块结构存储设备上的数据。底层PRP的窄宽度和对分数终端块的差处理是问题所在。虽然比(宽块)PRP-secure块密码更有效,但不如后者理想。

MACs(消息完整性但不加密)

ALG1–6: 一组MACs,全部基于CBC-MAC。方案太多了。有些方案被证明是VIL PRFs安全的,有些则是FIL PRFs安全的,还有一些没有可证安全性。其中一些方案存在破坏性攻击。某些模式已经过时。对于具有密钥分离的模式来说,其处理不足。不应大规模采用,但可以选择“最佳”方案。也可以选择不使用这些模式,而选择CMAC。ISO 9797-1 MAC中的一些模式被广泛标准化和使用,特别是在银行业。该标准的修订版本(ISO/IEC FDIS 9797-1:2010)即将发布[93]。

CMAC: 基于CBC-MAC的MAC,该模式被证明是(VIL)PRF(假设底层块密码是良好的PRP)安全的(直到生日界限)。与基于CBCMAC的方案相比,实际上不存在额外开销。固有的串行性质在某些应用领域是问题所在,并且在使用64位块密码时必须偶尔重新进行密钥更新。比ISO 9797-1 MAC集合更简洁。

HMAC: 基于加密哈希函数而不是块密码的MAC(尽管大多数加密哈希函数本身都基于块密码)。该机制享有强可证明安全界限,尽管并非首选假设。文献中存在多个密切相关的变体,这使得理解已知内容变得复杂。从未提出过破坏性攻击。被广泛标准化和使用。

GMAC: 一种基于nonce的MAC,是GCM的特殊情况。继承了GCM的许多优点和缺点。然而,MAC并不需要nonce,这里获得的好处很少。如果标签被截断为≤64位并且解密程度没有受到监控和限制,则存在实际攻击风险。在nonce重用时会完全失败。如果采用GCM,则使用是隐式的。不建议进行单独的标准化。

身份验证加密(加密和消息完整性)

CCM: 一种基于nonce的AEAD方案,将CTR模式加密和原始CBC-MAC结合使用。内在上是串行的,在某些情况下限制了速度。假定底层块密码是良好的PRP,具有良好的可证明安全性和较好的界限。设计虽繁琐但可行。比GCM更简单易实现。可以用作基于nonce的MAC。已广泛标准化和使用。

GCM: 一种基于nonce的AEAD方案,将CTR模式加密和基于GF(2128)的通用哈希函数组合使用。在某些实现环境中具有良好的效率特性。在最小标签截断的情况下具有良好的可证明安全性结果。在存在大量标签截断时存在攻击和差的可证明安全性界限。可以用作基于nonce的MAC,此时称为GMAC。允许使用96位以外的nonce是有问题的选择。建议将nonce限制为96位,并将标签至少限制为96位。已广泛标准化和使用。


1
GCM模式:鉴于SO上的大多数用户对加密知之甚少,不正确使用任何模式,通常不使用身份验证,并经常使用ECB模式。GCM模式可能是最好的选择在这里。不幸的是,由于平台实现的缺乏,在某些情况下(iOS)没有供应商支持,在许多情况下审核不严格,缺少硬件支持,它目前存在问题。否则,对于未接触过加密的人来说,它具有内置的身份验证功能,似乎是未来的发展方向。 - zaph
3
CTR模式:我不同意CTR模式是最佳选择,因为在实践中出现了许多故障,主要是IV重用。即使微软也至少犯了几次错误。 - zaph
1
CBC模式:可能是最常见的模式,也是SO上使用最多的模式,除了不应该使用的ECB。主要使用缺陷是非随机IV,但我们看到越来越多的正确用法与CSPRNG。填充神谕虽然是一个问题,但只需忽略并不返回填充错误即可轻松解决。一些实现(例如Common Crypto)在API级别避免填充错误的成功方式是不报告填充错误。 - zaph
1
在我看来,CTR 模式不太好,因为它只是一个简单的异或操作,而 CBC 模式则具有从块到块的传播效应,还有其他几种模式也是如此。虽然 CTR 看起来很简单,但在大众市场代码中已经发生了重大故障。 - zaph
1
@zaph 不,AES-GCM与AES-CTR非常不同(AES-CTR没有Galois乘法)。如果您声称在AES-CTR重复使用IV时可以恢复密钥,则您将是第一个提出这种主张的人,并且有责任提供证据。老实说,我可以向您保证,这种主张根本不是真的。 - TheGreatContini
显示剩余17条评论

31
  1. 避免使用ECB模式。
  2. 如果使用CTR模式,则每个消息都必须使用不同的IV,否则攻击者可以获取两个密文并推导出组合后的未加密明文。原因是CTR模式本质上将块密码转换为流密码,流密码的第一条规则就是永远不要重复使用相同的Key+IV。
  3. 在实现难度方面,各种模式之间没有太大差别。有些模式只需要块密码在加密方向上操作即可。然而,大多数块密码(包括AES)在实现解密时也不需要太多代码。
  4. 对于所有的密码模式,如果您的消息可能在前几个字节中完全相同,并且您不希望攻击者知道这一点,则重要的是为每个消息使用不同的IV。

1
不应该使用随机数开始CTR,因为这样会有一个小但逐渐增加的概率与先前消息的某个部分发生冲突。相反,应该单调递增它(这可能意味着记住在持久存储中的位置),并在计数器用完时重新键入。 - caf
1
关于第三点 - 我读过一些论文,例如,CTR模式更容易实现,因为解密和加密使用相同的转换。因此代码只需一半。但正如我所说,在服务器级别的计算机上,这并不重要。 - Cheeso
是的,我说错了。在CTR模式下应该更改IV / nonce,但它会与计数器组合在一起进行加密,因此我倾向于将其视为计数器的随机起点。至于只需在加密方向上使用密码来节省空间,对于许多密码,您只需要反转子密钥即可解密。AES解密有点笨重,但无论如何,您都无法在具有128字节RAM的uC上实现它。子密钥所需的RAM比128字节还要多! - Theran
@Cheeso:如果您正在发送具有相同密钥的多个消息(例如TLS/IPSec/...的多个数据包),则这些消息不应该都具有零初始化向量(而是具有递增或随机的向量)。如果您每条消息都更改密钥(例如在OpenPGP中),则可以毫无问题地从0开始。 - Paŭlo Ebermann
为了澄清,盐允许相同,但是nonce不允许相同,但可以以可预测的方式生成(例如按顺序),而IV不相同且不以可预测的方式生成。 - devnul3
显示剩余2条评论

11

8
这个答案不符合Stackoverflow的质量标准:请在您的回答中假设所有外部链接都已失效,并总结或直接复制相关信息,最好以最佳方式回答原始问题。 - mirabilos
5
@mirabilos 五年后谈论当时不存在的规范和标准,真的吗?我特别喜欢谈论死链,而这两个链接实际上仍然非常活跃,并且考虑到所涉及的站点可能在未来五年内仍将保持如此。哦,好吧。 - KTC
3
@mirabilos 你可能有道理,但是你对一个看起来是5年前发表的回答提出抱怨并不适用于当时的规范已经有所不同。你应该承认自己的错误。即使情况不是这样,你暗示它应该更新或更改,也不是义务性的。回答从当时的角度已经足够了。 - konsolebox
1
@KTC 除非政府关闭并且该网站离线,否则您的答案可能是有用的信息。但目前来看,它完全缺失。因此,这个问题及其答案的读者仍然不知道2014年更新了什么(由于答案不完整)以及当前状态(由于NIST网站被政府关闭)。我很想补充缺失的信息,但是... - G DeMasters
更新,如果你不想被踩。他们应该随意提出建议和评论,这正是它们存在的目的。 - Константин Ван
2022年:维基百科和NIST并没有消失,链接实际上回答了问题,而不是让提问者感到愚蠢。 - Sam Ginrich

10

你可能希望根据普遍可用的内容进行选择。我曾经有同样的问题,以下是我有限的研究结果。

硬件限制

STM32L (low energy ARM cores) from ST Micro support ECB, CBC,CTR GCM
CC2541 (Bluetooth Low Energy) from TI supports ECB, CBC, CFB, OFB, CTR, and CBC-MAC

开源软件的限制

Original rijndael-api source  - ECB, CBC, CFB1
OpenSSL - command line CBC, CFB, CFB1, CFB8, ECB, OFB
OpenSSL - C/C++ API    CBC, CFB, CFB1, CFB8, ECB, OFB and CTR
EFAES lib [1] - ECB, CBC, PCBC, OFB, CFB, CRT ([sic] CTR mispelled)  
OpenAES [2] - ECB, CBC 

[1] 这里提供了一个快速且易于使用的AES库。

[2] 这里可以下载OpenAES-0.8.0压缩包。


1
ST Micro:EBC 应该是 ECB;FYI:例如 STM32L4A6 支持 128 位和 256 位 AES,硬件还支持 ECB、CBC、CTR、GCM,以及 Galois 消息认证码(GMAC)或密码消息认证码模式 CMAC 链接算法。 - Tom Kuschel


-2
一般来说,链接模式的存在已经降低了理论上的安全性,因为链接扩大了攻击面并且也使某种类型的攻击更加可行。另一方面,如果没有链接,你最多只能安全地加密16个字节(128位),因为这是AES(包括AES-192和AES-256)的块大小,如果输入数据超过该块大小,除了使用链接之外,你还能做什么呢?一块一块地加密数据吗?那就是ECB,而ECB从一开始就具有最差的安全性。任何东西都比ECB更安全。
大多数安全分析建议您总是使用CBC或CTR中的一个,除非您可以说明为什么不能使用这两种模式之一。而在这两种模式之间,如果安全性是您的主要关注点,他们建议使用CBC,如果速度是您的主要关注点,则建议使用CTR。这是因为CTR比CBC稍微不太安全,因为它具有更高的IV(初始化向量)碰撞可能性,因为CTR计数器的存在减少了IV值空间,并且攻击者可以更改一些密文位来损坏明文中完全相同的位(如果攻击者知道数据中恰好的位位置可能会成为问题)。另一方面,CTR可以完全并行化(加密和解密),并且不需要将数据填充为块大小的倍数。

虽然如此,他们仍声称CFB和OFB是安全的,但相对不够安全,并且它们一开始就没有真正的优势。CFB与CBC共享相同的弱点,而且除此之外还不能防止重放攻击。OFB与CTR共享相同的弱点,但根本不能并行化。因此,CFB就像没有填充的CBC,但不够安全,而OFB就像CTR,但没有其速度优势并具有更广泛的攻击面。

只有一种特殊情况,你可能需要使用OFB,那就是如果你需要在实时解密数据(例如,一串流入数据)的硬件上进行解密,但是该硬件实际上过于薄弱无法满足要求,但你会提前知道解密密钥。在这种情况下,您可以预先计算所有XOR块并将其存储在某个地方,当真实数据到达时,整个解密过程只需将传入数据与存储的XOR块进行XOR操作,这需要非常少的计算能力。这是OFB可做到的唯一一件事,而其他链接方式均无法实现。

如需性能分析,请参见本文
如需详细评估,包括安全性,请参见本文


你不能使用CTR来预先计算吗?还是我遗漏了什么? - Leon Timmermans
1
@LeonTimmermans CTR是完全可并行化的,正如我之前所写的。但是它通过将IV从128位减少到96位来实现这一点,而在CTR中,IV碰撞是致命的(这是你可能产生的最严重的安全问题)。OFB仍然使用完整的128位作为IV,并且可以并行化,这就是为什么有时会使用它来替代CBC的原因,当你需要并行化但不能牺牲任何IV安全性时。 - Mecki

-4
我知道一个方面:尽管CBC通过为每个块更改IV提供更好的安全性,但它不适用于随机访问加密内容(如加密硬盘)。
因此,对于顺序流使用CBC(和其他顺序模式),对于随机访问使用ECB。

6
不需要解密之前的任何块,只需访问先前的密文即可。 - caf
啊,这意味着CBC对随机访问没有任何问题,不是吗? - Cheeso
4
CBC适用于随机读取,但不适用于随机写入。在这种情况下,请使用CTR。 - Paŭlo Ebermann
4
对于随机访问,CTR模式不是一个好的选择,因为如果攻击者观察到两个密文版本,则允许严重攻击。使用XTS或可调整块密码代替。 - CodesInChaos
1
在任何地方使用ECB模式都是毫无意义的。 - Antti Haapala -- Слава Україні
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接