使用 AES-256-CBC 与块加密的文件加密
File encryption with AES-256-CBC vs Chunk encryption
首先这是我在这里的第一个问题,我希望我可以让你清楚地了解这个问题并帮助其他可能面临类似挑战的人!问题的标题也是我能得到的最短的 TL;DR :-)
因此,为了给您一些背景信息,我基本上是在设计一个协议,该协议需要 同步和有序 来自服务器的文件传输(在 Node.js 中实现) ) 到设备,通过 TCP。流式传输文件不是一种选择,因此每个文件块都封装在一条消息中,该消息具有其他 non-encrypted 字段,这超出了该问题的范围。
其中一个要求是文件内容不能以明文形式发送,所以必须选择加密方案,在这种情况下我选择了AES-256-CBC,为了这道题的目的,假设算法不能改变。
由于设备限制(RAM ~10KB),需要将文件(<5 MB)拆分成块,然后根据提到的协议,遵循 send / [ack|repeat] 方案。在接收时,设备能够将块存储在磁盘上。
所以我的主要问题是在后端我必须选择:
加密整个文件然后分割成块
-> 在接收设备上会将每个块附加到文件中,然后在接收到所有块后对其进行解密。
vs
将文件分成块,然后对每个块进行加密。
-> 需要发送用于每个区块加密的 初始化向量 (IV) 才能对其进行解密。
-> 在块接收时,设备必须解密块或将每个块与各自的 IV 一起存储,然后在接收到最后一个块后解密它们。
此处的目标是了解每种方法产生的安全问题以及它们之间的开销比较。
PS:我也有完整性验证方案,但不在问题范围内。
为了回答您的问题,除了我在其他评论中提到的关键 AES 问题之外,我认为最好的方法是第二种解决方案。但在你的情况下,我会为每个块添加一个 HAMC。所以:
- 将文件分成块
- 为每个块生成一个 IV
- 使用相应的 IV 和 AES 密钥加密块
- 添加一个 HMAC(使用与加密不同的 AES 密钥,因此您需要 2 个 AES 密钥)计算每个块的 IV+Cipher_text(使用加密块而不是明文块很重要-块)
- 发送你的块
- 在设备上接收您的块。
- 检查每个块的 HMAC(这样它会确认块没有损坏并且经过良好验证)
- 用第一个密钥和相应的 IV 解密块
- 添加所有块以获取原始文件。
第二种更安全,因为您可以在解密之前控制所有块。
我的意思是,如果你逐块加密并添加一个HMAC,当你在你的设备上收到一个块时,首先你检查HMAC,如果没问题,你可以解密该块。这样,如果有人在您的网络上并试图破坏块或任何其他内容,HMAC 可以验证加密块的来源和内容。
虽然您的第一个选项无法做到这一点。如果有人试图在传输过程中破坏一个块,那么,最好的情况是你不能解密你的全局块,最坏的情况是它可能会向黑客提供一些关于加密系统的信息。它只是攻击者的一块拼图。这还不够,他需要更多的尝试才能解密一个块,但这是有风险的。
我觉得这个问题中遗漏了一些有助于更好地概述问题的部分,但从表面上看,根据所提供的信息,你可能会更好 第二个选项。
对于第一个选项,您限制了方案的可塑性,因为对于给定的块,由于使用 CBC 模式,您不太可能即时解密内容。虽然目前这可能不是您的计划的要求,但将来可能。
使用第二个选项,您可以将数据作为独立的 blob 传递。你可以随意对这些blob进行加密解密,需要的时候再组合起来。
每个选项可能还有 pros/cons,但您提供的方案详细信息并没有提供找出它们是什么的机会。我建议你谨慎行事。我知道您正在使用的设备有非常严格的要求,这使得传统密码学成为一种失去的奢侈品,但是设计和实现自己的密码系统是非常困难的,尤其是在如此严格的要求下。听起来你的方案没有提供前向保密,这意味着如果到了紧要关头,任何其他问题都可能是灾难性的。
首先这是我在这里的第一个问题,我希望我可以让你清楚地了解这个问题并帮助其他可能面临类似挑战的人!问题的标题也是我能得到的最短的 TL;DR :-)
因此,为了给您一些背景信息,我基本上是在设计一个协议,该协议需要 同步和有序 来自服务器的文件传输(在 Node.js 中实现) ) 到设备,通过 TCP。流式传输文件不是一种选择,因此每个文件块都封装在一条消息中,该消息具有其他 non-encrypted 字段,这超出了该问题的范围。
其中一个要求是文件内容不能以明文形式发送,所以必须选择加密方案,在这种情况下我选择了AES-256-CBC,为了这道题的目的,假设算法不能改变。
由于设备限制(RAM ~10KB),需要将文件(<5 MB)拆分成块,然后根据提到的协议,遵循 send / [ack|repeat] 方案。在接收时,设备能够将块存储在磁盘上。
所以我的主要问题是在后端我必须选择:
加密整个文件然后分割成块
-> 在接收设备上会将每个块附加到文件中,然后在接收到所有块后对其进行解密。
vs
将文件分成块,然后对每个块进行加密。
-> 需要发送用于每个区块加密的 初始化向量 (IV) 才能对其进行解密。
-> 在块接收时,设备必须解密块或将每个块与各自的 IV 一起存储,然后在接收到最后一个块后解密它们。
此处的目标是了解每种方法产生的安全问题以及它们之间的开销比较。
PS:我也有完整性验证方案,但不在问题范围内。
为了回答您的问题,除了我在其他评论中提到的关键 AES 问题之外,我认为最好的方法是第二种解决方案。但在你的情况下,我会为每个块添加一个 HAMC。所以:
- 将文件分成块
- 为每个块生成一个 IV
- 使用相应的 IV 和 AES 密钥加密块
- 添加一个 HMAC(使用与加密不同的 AES 密钥,因此您需要 2 个 AES 密钥)计算每个块的 IV+Cipher_text(使用加密块而不是明文块很重要-块)
- 发送你的块
- 在设备上接收您的块。
- 检查每个块的 HMAC(这样它会确认块没有损坏并且经过良好验证)
- 用第一个密钥和相应的 IV 解密块
- 添加所有块以获取原始文件。
第二种更安全,因为您可以在解密之前控制所有块。
我的意思是,如果你逐块加密并添加一个HMAC,当你在你的设备上收到一个块时,首先你检查HMAC,如果没问题,你可以解密该块。这样,如果有人在您的网络上并试图破坏块或任何其他内容,HMAC 可以验证加密块的来源和内容。
虽然您的第一个选项无法做到这一点。如果有人试图在传输过程中破坏一个块,那么,最好的情况是你不能解密你的全局块,最坏的情况是它可能会向黑客提供一些关于加密系统的信息。它只是攻击者的一块拼图。这还不够,他需要更多的尝试才能解密一个块,但这是有风险的。
我觉得这个问题中遗漏了一些有助于更好地概述问题的部分,但从表面上看,根据所提供的信息,你可能会更好 第二个选项。
对于第一个选项,您限制了方案的可塑性,因为对于给定的块,由于使用 CBC 模式,您不太可能即时解密内容。虽然目前这可能不是您的计划的要求,但将来可能。
使用第二个选项,您可以将数据作为独立的 blob 传递。你可以随意对这些blob进行加密解密,需要的时候再组合起来。
每个选项可能还有 pros/cons,但您提供的方案详细信息并没有提供找出它们是什么的机会。我建议你谨慎行事。我知道您正在使用的设备有非常严格的要求,这使得传统密码学成为一种失去的奢侈品,但是设计和实现自己的密码系统是非常困难的,尤其是在如此严格的要求下。听起来你的方案没有提供前向保密,这意味着如果到了紧要关头,任何其他问题都可能是灾难性的。