其中一个要求是它根本没有访问文件(它只读取固定大小的块,直到找到EOF)。算法需要数据字节是4的倍数,因此需要添加填充。
对于纯文本,一个好的解决方案是用NULL进行填充,在解密时忽略NULL,但是相同的策略不能用于二进制流(可能包含嵌入的NULL)。
我已经阅读了常见的解决方案,例如使用缺少字符的数量进行填充(如果缺少3个字符,则在末尾附加3、3、3等),但是我想知道:是否有更优雅的解决方案?
阅读: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
实际上,我认为一个好的流密码根本不需要填充。例如,RC4就不需要填充,而且是一种非常强大的流密码。但是,如果攻击者可以向加密例程提供不同的选择数据,该例程始终使用相同的密钥,并且还可以访问加密数据,则可以攻击它。选择正确的输入数据并分析输出数据可用于恢复加密密钥,而无需暴力攻击;但除此之外,RC4非常安全。
如果需要填充,那么在我看来它就不是流密码了。如果您填充为4字节的倍数或16字节的倍数,有什么巨大的区别呢?如果填充为16字节的倍数,您几乎可以使用任何块密码。实际上,您的密码是块密码,只是使用4字节块。在每个“符号”都是4字节的系统上(例如加密UTF-32文本的情况下),它是流密码,这种情况下数据肯定是4的倍数,因此永远不会有填充。