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

哪一个在什么情况下更受欢迎?

我想看看各种模式的评估标准列表,也许还有每个标准的适用性的讨论。

例如,< p > 我认为其中一个标准是用于加密和解密的“代码大小”,这对于微代码嵌入式系统很重要,比如802.11网络适配器。如果实现CBC所需的代码比CTR所需的代码要小得多(我不知道这是真的,这只是一个例子),那么我可以理解为什么使用较小代码的模式会更受欢迎。但如果我正在编写一个运行在服务器上的应用程序,而我使用的AES库同时实现了CBC和CTR,那么这个标准就无关紧要了。< / p >

看到我说的“评估标准清单和每个标准的适用性”了吗??

这与编程无关,但与算法有关。

486200 次浏览

你有没有开始阅读维基百科上的信息——分组密码的操作模式?然后按照维基百科上的参考链接到NIST:分组密码操作模式的建议

  1. 除了欧洲央行。
  2. 如果使用CTR,则必须为每条消息使用不同的IV,否则攻击者将能够获取两个密文并派生出未加密的明文。原因是CTR模式本质上将分组密码转换为流密码,而流密码的第一个规则是永远不要使用相同的Key+IV两次。
  3. 这两种模式的实现难度并没有太大区别。有些模式只要求分组密码在加密方向上操作。然而,大多数分组密码,包括AES,不需要太多代码来实现解密。
  4. 对于所有加密模式,如果您的消息在前几个字节可能是相同的,那么对每条消息使用不同的IVs是很重要的,并且您不希望攻击者知道这一点。

我知道一个方面:尽管CBC通过为每个块更改IV来提供更好的安全性,但它不适用于随机访问的加密内容(比如加密的硬盘)。

因此,对于顺序流使用CBC(和其他顺序模式),对于随机访问使用ECB。

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

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

  • 如果您想要良好的并行化,则使用CTR。speed),而不是CBC/OFB/CFB。

  • 如果您正在对随机可访问数据(如硬盘或RAM)进行编码,那么XTS模式是最常见的。

  • 到目前为止,OCB是最好的模式,因为它允许一次加密和身份验证。然而,在美国有专利。

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

  • 每次加密时都应该使用唯一的4,它们应该是随机。如果您不能保证它们是随机,请使用OCB,因为它只需要现时标志,而不是4,并且有明显的区别。现时标志不会降低安全性,如果人们可以猜出下一个,4会导致这个问题。

你可能想要根据广泛可用的来选择。我也有同样的问题,以下是我有限研究的结果。

硬件的限制

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] # EYZ0

[2] # EYZ0

如果您无法实现自己的密码学,请考虑长期和困难

问题的丑陋真相是,如果你问这个问题,你可能无法设计和实现一个安全的系统。

让我来说明我的观点:假设你正在构建一个web应用程序,你需要存储一些会话数据。您可以为每个用户分配一个会话ID,并将会话数据以映射会话ID到会话数据的散列映射的形式存储在服务器上。但随后你必须在服务器上处理这种烦人的状态,如果在某个时候你需要多个服务器,事情就会变得混乱。因此,您可以将会话数据存储在客户端的cookie中。当然,您将对其进行加密,这样用户就无法读取和操作数据。那么应该使用哪种模式呢?来到这里,你看到了上面的答案(对不起,我把你挑出来了)。第一个覆盖的- ECB -不适合你,你想加密多个区块,下一个- CBC -听起来不错,你不需要CTR的并行性,你不需要随机访问,所以没有XTS和专利是一个PITA,所以没有OCB。使用您的加密库,您意识到您需要一些填充,因为您只能加密块大小的倍数。您选择PKCS7是因为它在一些严格的密码学标准中定义。在某处读到CBC是证明地安全,如果与随机IV和安全分组密码一起使用,即使您在客户端存储敏感数据,您也可以放心。

多年以后,在您的服务确实发展到相当大的规模之后,一位IT安全专家以负责任的方式与您联系。她告诉您,她可以使用填充oracle攻击解密您的所有cookie,因为如果填充以某种方式损坏,您的代码将生成一个错误页面。

# EYZ0 # EYZ1

问题是关于密码学有很多陷阱,构建一个对外行来说看起来很安全,但对有知识的攻击者来说是微不足道的系统是非常容易的。

如果需要加密数据,该怎么做

对于使用TLS的实时连接(请确保检查证书的主机名和颁发者链)。如果您不能使用TLS,请寻找您的系统必须为您的任务提供的最高级API,并确保您了解它提供的保证,以及更重要的是它不能保证什么。对于上面的例子,像这样的框架提供了客户端存储设施,它不会在一段时间后使存储的数据失效,但是,如果您更改了客户端状态,攻击者可以在您不注意的情况下恢复以前的状态。

如果没有高级抽象可用,则使用高级加密库。一个突出的例子是生理盐水,一个具有许多语言绑定的可移植实现是。使用这样的库,你不必关心加密模式等,但你必须更加注意使用细节,而不是使用更高层次的抽象,比如永远不要使用两次nonce。对于自定义协议构建(比如你想要TLS之类的东西,但不是基于TCP或UDP),有噪音这样的框架和相关实现可以为你做大部分繁重的工作,但它们的灵活性也意味着有很大的出错空间,如果你不深入了解所有组件的功能。

如果由于某种原因,你不能使用高级加密库,例如,因为你需要以特定的方式与现有系统交互,那么就没有办法彻底自学。我推荐阅读由Ferguson, Kohno和Schneier撰写的密码工程。请不要欺骗自己,相信没有必要的背景就可以构建一个安全的系统。密码学是非常微妙的,几乎不可能测试系统的安全性。

模式比较

只加密:

    <李> # EYZ0: 与示例中一样,填充通常是危险的,因为它为填充oracle攻击提供了可能性。最简单的防御方法是在解密之前对每个消息进行身份验证。见下文。
    • 欧洲央行对每个数据块进行独立加密,相同的明文块将产生相同的密文块。看看欧洲央行在欧洲央行维基百科页面上加密的Tux图像,看看为什么这是一个严重的问题。我不知道有哪个用例是可以接受欧洲央行的。
    • 加拿大广播公司有一个IV,因此每次加密消息都需要随机性,更改消息的一部分后需要重新加密所有内容,一个密文块中的传输错误完全破坏明文并更改下一个块的解密,解密可以并行/加密不能,明文在一定程度上具有延展性- 这可能是个问题
  • 流密码模式:这些模式生成伪随机数据流,可能依赖于明文,也可能不依赖于明文。与一般的流密码类似,生成的伪随机流与明文进行xor,生成密文。因为你可以使用任意多的随机流,你根本不需要填充。这种简单的缺点是加密完全# EYZ1,意味着解密可以被攻击者以任何方式改变他喜欢作为明文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很简单,它创建了一个独立于明文的伪随机流,不同的伪随机流是通过从不同的nonces/IVs中计数获得的,这些nonces/IVs乘以最大消息长度,以防止重叠,使用nonces消息加密是可能的,而不是每个消息的随机性,解密和加密是并行完成的,传输错误只影响错误的位,没有别的
    • OFB还创建了一个独立于明文的伪随机流,不同的伪随机流通过从每个消息的不同的nonce或随机IV开始获得,加密和解密都是不可并行的,就像CTR使用nonce消息加密一样,没有每个消息的随机性,CTR传输错误只影响错误的位,没有更多
    • 循环流化床的伪随机流依赖于明文,每个消息都需要不同的nonce或随机IV,就像CTR和OFB使用nonce消息加密是可能的,没有每个消息的随机性,解密是可并行的/加密不是,传输错误完全破坏下面的块,但只影响当前块中的错误位
  • < a href = " https://en.wikipedia.org/wiki/Disk_encryption_theory " rel = " noreferrer " > < / >磁盘加密模式:这些模式专门用于加密文件系统抽象层以下的数据。为了提高效率,修改磁盘上的某些数据只需要重写最多一个磁盘块(512字节或4kib)。它们超出了这个答案的范围,因为它们的使用场景与其他应用程序有很大不同。# EYZ1。部分成员:XEX, XTS, LRW。

认证加密:

为了防止填充oracle攻击和对密文的修改,可以在密文上计算一个消息认证码 (MAC),只有在密文没有被篡改的情况下才能解密。这被称为加密然后mac和应该优先于其他订单吗。除了极少数用例之外,真实性与保密性同样重要(后者是加密的目的)。经过身份验证的加密方案(带有关联数据(AEAD))将加密和身份验证这两部分过程组合成一个分组密码模式,该模式还在该过程中产生一个身份验证标记。在大多数情况下,这会提高速度。

  • CCM是CTR模式和CBC-MAC模式的简单组合。使用两个区块密码加密每个区块是非常慢的。
  • 台籍干部速度更快,但受到专利的阻碍。然而,对于免费(自由)或非军事软件,专利持有人是否授予了免费许可证
  • GCM是CTR模式和GHASH的非常快速但可以说是复杂的组合,GHASH是一个具有2^128个元素的伽罗瓦场的MAC。它在像TLS 1.2这样的重要网络标准中的广泛应用反映在英特尔为加快GHASH计算而引入的特殊指令中。

推荐:

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

Phil Rogaway在2011年做了一个形式化分析,在这里。第1.6节给出了我在这里记录的摘要,并以粗体添加了我自己的重点(如果您没有耐心,那么他建议您使用CTR模式,但我建议您阅读下面关于消息完整性与加密的段落)。

请注意,其中大多数要求IV是随机的,这意味着不可预测,因此应该使用加密安全性生成IV。然而,有些只要求“nonce”,它不要求该属性,而只要求它不被重用。因此,依赖于nonce的设计比不依赖于nonce的设计更不容易出错(相信我,我见过许多没有正确选择IV的情况下实现CBC的情况)。因此,当Rogaway说“当IV是nonce时,机密性不会实现”之类的话时,您将看到我添加了粗体,这意味着如果您选择的IV是加密安全的(不可预测的),那么就没有问题。但是如果你不这样做,那么你就失去了良好的安全性。不要重复使用静脉注射用于任何这些模式。

此外,理解消息完整性和加密之间的区别也很重要。加密会隐藏数据,但是攻击者可能会修改加密的数据,如果您不检查消息完整性,那么结果可能会被您的软件接受。虽然开发人员会说“但是修改后的数据在解密后会作为垃圾返回”,但优秀的安全工程师会发现垃圾在软件中导致不良行为的可能性,然后他会将这种分析转化为真正的攻击。我见过许多使用加密的情况,但实际上更需要消息完整性而不是加密。了解你需要什么。

我应该说,尽管GCM具有加密和消息完整性,但它是一种非常脆弱的设计:如果你重复使用IV,你就完蛋了——攻击者可以恢复你的密钥。其他设计没有那么脆弱,所以我个人不敢推荐GCM,因为我在实践中看到了大量糟糕的加密代码。

如果你同时需要消息完整性和加密,你可以结合两种算法:通常我们看到CBC和HMAC,但没有理由把自己绑定到CBC。重要的是要知道先加密,再对加密后的内容进行MAC,而不是相反。此外,IV需要成为MAC计算的一部分。

我不了解知识产权问题。

下面是罗格威教授的好消息:

分组密码模式,加密但不消息完整性

欧洲央行:区块密码,该模式通过单独加密每个n位块来加密n位倍数的消息。安全属性较弱,该方法在块位置和时间上泄漏块的相等性。具有相当大的遗留价值,以及作为其他方案的构建块的价值,但该模式本身并不能实现任何普遍可取的安全目标,必须非常谨慎地使用;# EYZ2。

加拿大广播公司:基于IV的加密方案,该模式作为概率加密方案是安全的,实现了与随机位的不可区分性,假设是随机IV. 如果IV只是暂时的,机密性就无法实现,如果它是在该方案使用的同一密钥下进行的nonce加密,就像标准错误地建议的那样。密文具有高度的延展性。无选择密文攻击(CCA)安全。对于许多填充方法,存在正确填充oracle时,机密性就会丧失。固有的串行加密效率很低。该模式的仅隐私安全属性被广泛使用,导致了频繁的误用。可以用作CBC-MAC算法的构建块。# EYZ2

循环流化床:基于IV的加密方案,该模式作为概率加密方案是安全的,实现与随机位的不可区分性,假设是随机IV. 如果IV是可预测的,则不能实现保密性,如果它是由在该方案使用的相同密钥下的nonce加密而成,正如标准错误地建议的那样。密文是可塑的。没有CCA-security。固有的串行加密效率很低。方案取决于一个参数s, 1≤s≤n,典型为s = 1或s = 8。只需要一个blockcipher调用处理s位,效率很低。该模式实现了一个有趣的“自同步”属性;在密文中插入或删除任意数量的s位字符只会暂时中断正确的解密。

OFB:基于IV的加密方案,该模式作为概率加密方案是安全的,实现与随机位的不可区分性,假设IV是随机的。如果IV是nonce,则无法实现机密性,尽管固定的IV序列(例如计数器)确实工作得很好。密文具有高度的延展性。没有CCA安全性。由于固有的串行性,加密和解密效率低下。本地加密任何位长度的字符串(不需要填充)。我看不出CTR模式有什么重要的优势。

CTR:一个基于IV的加密方案,该模式实现了与随机位的不可区分性,假设一个nonce IV。作为一个安全的基于non的方案,该模式也可以作为一个随机IV的概率加密方案。如果一个nonce在加密或解密时被重用,则隐私完全失败。该模式的并行性通常使其速度更快,在某些设置下比其他保密模式快得多。身份验证加密方案的重要组成部分。# EYZ1

xt:基于iv的加密方案,该模式通过对每个n位块应用可调整的块密码(安全为强- prp)来工作。对于长度不能被n整除的消息,最后两个块被特殊处理。该模式只允许用于对块结构存储设备上的数据进行加密。底层PRP的宽度窄,分数阶终块处理不好是问题。比(宽块)prp安全块密码更有效,但不太理想。

mac(消息完整性,而不是加密)

ALG1-6: mac的集合,它们都基于CBC-MAC。太多的计划。有些是可证明的VIL prf,有些是可证明的FIL prf,有些则没有可证明的安全性。一些计划承认有破坏性的攻击。有些模式已经过时了。对于具有键分离的模式,没有充分注意键分离。不应该全部采用,但有选择地选择“最佳”方案是可能的。为了支持CMAC,不采用这些模式也很好。一些ISO 9797-1 mac被广泛标准化和使用,特别是在银行业。标准的修订版(ISO/IEC FDIS 9797-1:2010)将很快发布[93]。

小脑模型:基于CBC-MAC的MAC,该模式作为(VIL) PRF可证明是安全的(直到生日界限)(假设底层块密码是一个良好的PRP)。基本上是基于cbcmac的方案的最小开销。在某些应用程序域中,固有的串行特性是一个问题,并且使用64位块密码将需要偶尔重新输入密钥。比ISO 9797-1系列的mac更干净。

HMAC:基于加密哈希函数而不是区块密码的MAC(尽管大多数加密哈希函数本身是基于区块密码的)。机制具有很强的可证明安全界限,尽管不是来自首选的假设。文献中多个密切相关的变体使理解已知的东西变得复杂。没有任何破坏性攻击的建议。广泛标准化和使用。

通用汽车金融服务公司(GMAC):一个非基于MAC,是GCM的特殊情况。继承了GCM的许多好的和坏的特性。但是对于MAC来说,“无要求”是不必要的,而且在这方面它几乎没有什么好处。如果标记被截断到≤64位,并且解密的范围没有被监控和限制,则实际攻击。在非重用上完全失败。如果采用GCM,则使用是隐式的。不建议单独标准化。

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

CCM:结合CTR模式加密和原始加密的非基于AEAD方案 CBC-MAC。固有的串行性,在某些情况下限制了速度。可证明的安全,具有良好的边界,假设底层区块密码是一个良好的PRP。笨拙的结构,显然能做到。实现起来比GCM简单。可以作为一个非基于MAC。广泛标准化和使用。

GCM:结合CTR模式加密和基于GF(2128)的通用哈希函数的基于非ce的AEAD方案。在某些实现环境中具有良好的效率特性。良好的可证明安全的结果,假设最小的标签截断。在存在大量标签截断的情况下,攻击和较差的可证明安全边界。可以用作非基于MAC,然后称为GMAC。允许非96位nonce的选择值得怀疑。建议将nonce限制为96位,标签限制为至少96位。广泛标准化和使用。

一般来说,单一的链式模式已经降低了理论上的安全性,因为链式模式扩大了攻击面,也使某些攻击更加可行。另一方面,如果没有链接,你最多可以安全地加密16字节(128位),因为这是AES (AES-192和AES-256)的块大小,如果你的输入数据超过了这个块大小,除了使用链接,你还能做什么?只是一个块一个块地加密数据?那将是欧洲央行,而欧洲央行的安全措施是最糟糕的。任何东西都比欧洲央行更安全。

大多数安全分析建议您始终使用CBC或CTR,除非您能说出不能使用这两种模式之一的任何原因。在这两种模式中,如果您主要考虑的是安全性,他们推荐CBC模式,如果您主要考虑的是速度,则推荐CTR模式。这是因为CTR的安全性略低于CBC,因为它具有更高的IV(初始化向量)碰撞的可能性,因为CTR计数器的存在减少了IV值空间,并且攻击者可以更改一些密文位来破坏明文中的完全相同的位(如果攻击者知道数据中的确切位位置,这可能是一个问题)。另一方面,CTR可以完全并行化(加密和解密),并且不需要数据填充到块大小的倍数。

也就是说,他们仍然声称CFB和OFB是安全的,但稍微不太安全,他们一开始就没有真正的优势。CFB与CBC有相同的弱点,最重要的是不能防止重放攻击。OFB与CTR具有相同的弱点,但完全不能并行。所以CFB就像没有填充的CBC,但更不安全,OFB就像CTR,但没有速度优势和更宽的攻击面。

只有一种特殊情况下,你可能想要使用OFB,那就是如果你需要在硬件上实时解密数据(例如输入的数据流),这实际上太弱了,但你会提前知道解密密钥。在这种情况下,你可以预先计算所有的异或块,并将它们存储在某个地方,当真正的数据到达时,整个解密只是用存储的异或块对传入的数据进行异或,这只需要很少的计算能力。这是你可以用OFB做的一件事,你不能用任何其他链接。

性能分析参见这篇论文
有关详细的评估,包括安全性,请参见这篇论文