填充 - 加密算法

3
我正在编写一个XXTEA加密算法的实现,它可以用于“流”,即可以像这样使用:crypt mykey < myfile > output。
其中一个要求是它根本没有访问文件(它只读取固定大小的块,直到找到EOF)。算法需要数据字节是4的倍数,因此需要添加填充。
对于纯文本,一个好的解决方案是用NULL进行填充,在解密时忽略NULL,但是相同的策略不能用于二进制流(可能包含嵌入的NULL)。
我已经阅读了常见的解决方案,例如使用缺少字符的数量进行填充(如果缺少3个字符,则在末尾附加3、3、3等),但是我想知道:是否有更优雅的解决方案?

你为什么要自己实现这个而不使用现有的实现呢?很容易意外地创建一个不安全的加密系统。 - Nick Johnson
主要原因是为了学习。 我已经改变了范围,现在我让它适用于“文件”,这使我能够获取总大小并写入一个标题,以通知添加的填充量。感谢所有的评论和建议。 - Kknd
4个回答

4

阅读:http://msdn.microsoft.com/en-us/library/system.security.cryptography.paddingmode.aspx

它列出了常见的填充方法,如:

PKCS7 - PKCS #7填充字符串由一系列字节组成,每个字节都等于添加的填充字节的总数。

ANSIX923填充字符串由长度之前填充零的一系列字节组成。

ISO10126填充字符串由长度之前的随机数据组成。

例子:

原始数据:01 01 01 01 01

PKCS#7:01 01 01 01 01 03 03 03

ANSIX923:01 01 01 01 01 00 00 03

ISO10126:01 01 01 01 01 CD A9 03


4

阅读密文窃取。这比明文填充更加优雅。另外,建议使用大于4字节的块大小,64位可能是最低要求。

严格来说,自己动手进行密码学是一个危险的想法;很难击败整个密码社区都试图并未能破解的算法。尽情享受,并考虑阅读this或者至少阅读Schneier的“相关阅读”部分中的一些内容。


1
他正在使用一个知名的同行评审出版算法。使用现成的闭源库可能是个坏主意,这些算法可能很棒,但你不知道它们有什么后门。 - Martin Beckett
他也没有说他正在使用哪种链接模式。使用公认的安全密码仍然可以构建一个不安全的加密系统。 - Nick Johnson

2
阅读问题,看起来安全方面的问题是无关紧要的。简单来说,您有一个期望输入为4个字节的倍数的API,但并非总是如此。
将多达3个字节附加到任何二进制流中可能是危险的,如果您不能保证二进制流不在意这些。将0附加到exe文件的末尾不重要,因为exe文件具有指定所有剩余位的相关大小的标头。将0附加到pcx文件的末尾会破坏它,因为pcx文件具有从文件末尾开始的特定字节数的标头。
所以你真的没有选择-你不能使用保证从不自然发生在二进制流末尾的神奇填充字节的选择:您必须始终附加至少一个额外的字描述所使用的填充字节的信息。

-1

实际上,我认为一个好的流密码根本不需要填充。例如,RC4就不需要填充,而且是一种非常强大的流密码。但是,如果攻击者可以向加密例程提供不同的选择数据,该例程始终使用相同的密钥,并且还可以访问加密数据,则可以攻击它。选择正确的输入数据并分析输出数据可用于恢复加密密钥,而无需暴力攻击;但除此之外,RC4非常安全。

如果需要填充,那么在我看来它就不是流密码了。如果您填充为4字节的倍数或16字节的倍数,有什么巨大的区别呢?如果填充为16字节的倍数,您几乎可以使用任何块密码。实际上,您的密码是块密码,只是使用4字节块。在每个“符号”都是4字节的系统上(例如加密UTF-32文本的情况下),它是流密码,这种情况下数据肯定是4的倍数,因此永远不会有填充。


TEA是一种块密码,他只想在流程序中使用它。填充是标准解决方案,可以使用特定的魔法值进行移除,或者使用头部给出数据长度。 - Martin Beckett

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