• 手机版

    扫码体验手机版

  • 微信公众号

    扫码关注公众号

游客您好
第三方账号登陆
  • 点击联系客服

    在线时间:8:00-16:00

    客服电话

    400-123-4567

    电子邮件

    1691000615@qq.com
  • 星点互联APP

    随时掌握企业动态

  • 扫描二维码

    关注星点微信公众号

Lv.4 学员组
5号会员,31活跃度,2019/01/10 加入学习
  • 10发帖
  • 10主题
  • 0关注
  • 0粉丝
非常流弊,不废话。。。。。
优秀讲师更多
课堂交流更多
开启左侧

[面试技巧] 最佳安全实践:在 Java 和 Android 中使用 AES 进行对称加密

[复制链接]
DeJay王健 发表于 2019-1-11 12:16:37 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
为什么每一个软件工程师都需要知道 AES
AES,又称 Rijndael 加密算法,在2000 年被 NIST 选中以用来替换过时的数据加密标准(DES)。AES 是一种分组密码,这意味着加密发生在固定长度的比特组上。在我们的例子中,算法定义块长度为 128 位。AES 支持 128,192 和 256 位的密钥长度。
每个块都经历多轮转换。我将在这里省略算法的细节,对算法感兴趣的读者可以参考维基百科中有关 AES 的文章。这里需要指出的是块大小受转换轮次的重复次数影响(128 位密钥是 10 个周期,256 位为 14 个周期),而密钥长度并不影响它的大小。
一直到 2009 年 5 月,唯一一次成功发布,针对完整 AES 的攻击是对某些特定实现的旁道攻击。(资源)
想要加密多个块?
AES 只会加密 128 位数据,如果我们想要加密整个消息,我们需要选择一种块模式,利用该模式可以将多个块加密为一个密文。最简单的块模式是电子密码本或 ECB。它将在每个区块中使用相同的未更改的键:
                              
图片来自维基百科
这将是特别糟糕的,因为相同的明文会被加密成相同的密文。

使用 ECB 块模式加密的图片显示原始图案(自己尝试一下点击预览)
请记住,除非你只加密小于 128 位的数据,否则永远不要选择该模式。不幸的是,它仍然被经常误用,因为它不需要你提供初始向量(稍后会详细介绍),因此开发人员似乎更容易处理。
必须使用块模式处理的一种情况:如果最后一个块的大小不足 128 位会发生什么?这就是填充发挥作用的地方,即填充块的缺失位。最简单的方式是用零填充缺失位。在 AES 中选择填充几乎没有任何安全隐患。
密码分组链接(CBC)
那么有什么方案可以替代 ECB 呢?例如 CBC,在该模式中,用当前的明文块和前一个密文块进行异或。在该方法中,每个密文块都依赖于它前面的所有明文块。使用与之前相同的图片,加密结果将是与噪声数据无法区分的随机数据:

使用 CBC 块模式加密的图片看起来是随机的
那如何处理第一个块呢?最简单的方法是使用一个完整的填充块(比如用零填充),但这样每次加密相同密钥和明文都会产生一样的密文。此外,如果你为不同的明文重用相同的密钥,那么恢复密钥将会更加容易。更好的方法是使用随机初始化向量(IV。这对于随机数据来说只是一个奇特的词,大约是一个块(128 位)大小。将它想象成一个加密的 salt,也就是说,IV 是可以公开的,随机的且只能使用一次。但请注意,因为 CBC 将密文异或而不是前一个明文的明文,因此 IV 不仅仅会阻止第一个块的解密。
在传输或保持数据时,通常只将 IV 添加到实际的密码消息中。如果你对如何正确使用 AES-CBC 感兴趣,请阅读本系列的第 2 部分。
记数模式(CTR)
另外一种选择是使用 CTR 模式。这种模式很有意思,因为它会将密码转换为密码流,这意味着不需要进行填充。在其基本形式中,所有块的编号为 0 到 n。现在每个块都将使用密钥、IV(此处也称为 nonce)和计数器的值来进行加密。

图片来自维基百科
与 CBC 不同,它的优点是可以进行并行加密并且所有块都依赖于 IV,而不仅仅是第一个。一个很严重的警告是,IV 永远不能被相同的密钥重用,因为攻击者可以从中轻松计算出你所使用的密钥。
我可以确保没有人能够修改我的消息吗?
事实:加密不会自动防止数据修改。这实际上是一种非常常见的攻击。有关该问题更全面的讨论,请阅读此文。
那么我们又能做些什么呢?我们只需将加密验证码(MAC)添加到加密邮件中。MAC 类似于数字签名,不同之处在于验证和验证密钥实际上是相同的。这种方法有不同的变化,大多数研究人员推荐的模式叫做Encrypt-then-Mac 。也就是说,在加密之后,在密文上计算并附加 MAC。你通常会使用基于哈希的消息身份验证代码(HMAC)作为 MAC 的类型。
现在它开始变得复杂了。为了完整性/真实性我们必须选择 MAC 算法,选择加密标签模式,计算 mac 并附加它。因为整个消息必须处理两次,所以该操作运行速度缓慢。反向操作必须与前面一致,但用于解密和验证。
使用 GCM 进行认证加密
如果有模式可以处理所有的身份验证,那不是很好吗?幸运的是有一种称为认证加密的加密方式,它同时为数据的机密性、完整性和真实性提供了保证。支持此功能最流行的块模式之一为 Galois/Counter Mode or GCM(比如它可以使用 TLS v1.2 中的密码组件)。
GCM 基于 CTR 模式,它还在加密期间顺序计算身份验证标记。然后该标记通常会附加到密文中。它的大小是一个重要的安全属性,因此它的长度至少是 128 位。
它还可以验证未包括在明文中的附加信息。该数据称为关联数据。这为什么有用呢?例如,加密数据具有元属性,即用于检查是否必须重新加载内容的创建日期。攻击者可以轻松更改创建日期,但如果将其添加为关联数据, CGM 将验证此信息并识别出更改。
激烈的讨论:使用多长的密钥?
直觉会说:越大越好 - 很明显,强制 256 位随机值比128 位更难。根据我们目前的理解,强制通过 128 位长字节的所有值都需要天文数量的能量,对于任何在合理时间内的人来说都是不现实的(看着你,NSA)。因此,决定基本上在无限和无限时间 212⁸ 之间。
AES 实际上有三种不同的密钥大小,因为它被选为美国联邦政府的标注加密算法以用于联邦政府「包括军方」控制的各个领域。(...)因此,精明的军事首脑提出了应该有三个“安全级别”的想法,以便使用重量级方法加密最重要的秘密,但较低价值的数据可以用更实用,更轻量级的算法加密。(...)因此,NIST 决定正式遵守规定(要求三个关键尺寸),但也要做前瞻性的事(最低级别必须通过可遇见的技术不可攻破)(来源)。
论点如下:AES 加密消息可能不会被暴力破坏密钥破坏,而是通过其他较便宜的攻击(当前未知)。这些攻击对于 128 位密钥模式和 256 位模式一样有害,因此在这种情况下选择更大的密钥大小也无济于事。
所以基本上 128 位密钥对于大多数用例来说都足够安全,但量子计算机保护除外。同样使用比 256 位更快的 128 位加密。128位密钥的密钥强度似乎可以更好的防止相关密钥攻击(但这与大多数实际用途无关)。
旁注:旁道攻击
旁道攻击是利用特定于某些实现的问题的攻击。加密密码方案本身不能有效地保护它们。简单的 AES 实现可能容易发生计时,缓存攻击及其他攻击。
作为一个非常基本的例子:一个容易发生定时攻击的简单算法是一个比较两个秘密字节数组的 equals() 方法。如果 equals() 有一个快速返回,意味着在第一对不匹配的字节结束循环之后,攻击者可以测量 equals() 完成所需要的时间,并且可以一个字节一个字节的猜测,直到全部匹配为止。

使用快速返回可能受到定时攻击的代码
在这种情况下,一个修复方法是使用恒定时间等于。请注意,在类似于 JVM 等解释语言中编写常量时间代码往往并非易事。
针对 AES 的定时和缓存攻击不仅仅是理论上的,甚至可以通过网络进行实施。虽然防止旁道攻击主要是实施加密原语的开发人员关注的问题,但了解编码实践可能对整个例程的安全性有害是明智的。最一般的主题是,可观察到的与时间相关的行为不应该依赖于私密数据。此外,你应该仔细考虑要选择的实现方案。例如,使用带有 OpenJDK 的 Java 8+和默认的 JCA 提供程序应该在内部使用 Intel 的 AES-NI 指令集,该指令集通过恒定时间和在硬件中实现(同时仍具有良好的性能)来防止大多数时序和缓存攻击。Android 使用它的 AndroidOpenSSLProvider,内部可能会在硬件中使用 AES(ARM TrustZone),具体取决于 SoC。但我不相信它具有与 Intelspedant 相同的防护。但即使你改进硬件,也可以使用其他攻击向量,例如功率分析。存在专门用于防止大多数这些问题的专用硬件,即硬件安全模块(HSM)。不幸的是,这些设备的成本通常高达数千美元(有趣的是:你的基于芯片的信用卡也是 HSM)。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz!X3.5 ©2001-2013 Comsenz Inc.星点互联设计( 鲁ICP(125234543) )