1

我正在用 C 编写服务器,我想用 aes 对文件进行编码。

据我所知,编码块大小应该等于 AES 密钥长度,所以我需要用零将最后一个块补足到所需的大小。问题在于解码:如何区分文件内容和补零?好吧,我计划为此使用 Base64 编码,但是对于大文件来说是不是太慢了?可能我应该在发送编码块之前发送文件大小吗?

4

3 回答 3

3

一个常见的方案是 PKCS#5 填充。基本上,用等于填充长度的字节填充(明文的)填充。然后,解密后,查看最后一个字节,看看要丢弃多少。确认丢弃的字节相同可提供快速的完整性检查。一些示例,以十六进制表示:

[AABBCCDD EEFF0011 22334455 667788--] -> [AABBCCDD EEFF0011 22334455 66778801]
[AABBCCDD EEFF0011 22334455 66------] -> [AABBCCDD EEFF0011 22334455 66030303]
[AABBCCDD EEFF0011 22334455 66778899] -> [AABBCCDD EEFF0011 22334455 66778899][10101010 10101010 10101010 10101010]
//the last byte must be padding, even if that requires an extra block

旁注:如果您自己实施加密,请阅读操作模式。如果不是,那么您使用的任何库都应该能够处理填充。

于 2012-04-24T22:19:56.393 回答
2

对文件进行 Base64 编码然后进行 AES 加密并不是一个好主意。这样做通过将密文的每个字节的高 2 位设置为已知值,将可能的块数从 2^64 减少到 2^48。

我不确定这是“最好”还是“正常”的方法,但我通常会在我的密文的开头或结尾添加几个额外的块,这些块将解密为有关文件的元数据 - 大小、文件名、内容类型等。是的,这些块的熵非常小,但允许一个或两个带有婴儿床的块比让每个字节包含一个要好得多。

例如,如果您有一个 10 字节长的文件,那么您将拥有一个完整的密文块,该块包含两个有用字节,后跟 6 个字节的填充。最后一个块将包含您的元数据。(实际上,元数据块可以放在开头或结尾。随你选。)

于 2012-04-24T22:18:09.167 回答
0

请参阅有关填充方案的此页面:

http://en.wikipedia.org/wiki/Padding_ (密码学)

例如对于 CBC 模式:

一种方法是用 1 位后跟 0 位来填充最后一个块。如果输入恰好填满了整个块,则会添加一个“虚拟块”来容纳填充;否则,输入明文的结尾可能会被误解为填充。另一种方法是在明文末尾附加 n 个字节,其值为 (n-1),以填充一个完整的块。如果消息已经完全填满了一个块,那么出于与之前相同的原因,将添加一个完整的填充块块。这意味着填充是一个字节的 0 或两个字节的 1 等。

如果您使用 CTR 模式,则甚至不需要填充,因为密文与纯文本的大小相同。

正如@maybewecouldstealavan 所指出的,流行的填充方案是来自 RSA 实验室的 PKCS #5。这是 OpenSSL 程序用于 CBC 模式的填充方案。

所有分组密码通常使用 PKCS#5 填充,也称为标准分组填充:这允许执行基本的完整性或密码检查。

http://www.openssl.org/docs/apps/enc.html

于 2012-04-24T22:45:32.603 回答