我正在使用PHP编写一个应用程序,用户可以使用几种可能的算法多次加密他的文本。起初我认为这很简单,但后来我想到了当数据填充到块大小,加密然后解密时发生的问题。
起初我以为我可以在每次解密过程之后删除空字节,以便在填充之前获取原始数据。现在,如果数据在末尾本身有几个空字节,那么在解密过程之后删除空字节只会删除部分原始数据并以丢失数据结束,也可能是错误的解密(最后一点取决于块大小)以下解密算法)。虽然几个加密过程后的数据或数据包含几个空字节的可能性几乎为零,但我正在寻找解决上述问题的解决方案。
如果我不想从数据中删除空字节,我也会得到一些恼人的结果,具体取决于使用的算法的块大小。为了表明我编写了一个python程序,它有三个加密算法,一个用2个字节的块大小进行操作,另一个用块大小为3,最后一个块大小为4,所以你可以把它们比作128-, 192位和256位算法。我从一些随机字节开始并多次加密,然后在每次解密过程后解密它们而不删除空字节。程序员以十六进制格式打印每个解密/加密过程后的字节,这里是输出,带有一些评论:
48 61 6c 6c 6f //thats our data at the start
da b4 28 fe 9e 4a //now the 3-byte algorithm was run -> padded to 6 bytes
5e 62 04 72 1a d8 d2 a4 //used the 4-byte algorithm -> padded to 8 bytes
cc a1 43 e0 f5 e7 40 eb 81 //3-byte algorithm used again -> padded to 9 bytes
48 61 7a 07 71 1e 3f 0f 05 8d 98 a4 //at last used the 4-byte algorithm -> padded to 12 bytes
cc a1 43 e0 f5 e7 40 eb 81 00 00 00 //first encryption done, notice the three null-bytes and the similarity to line 4
5e 62 04 72 1a d8 d2 a4 00 92 0f 2a //secound encryption done, not removed null-bytes "decrypted", but the rest goes well, as seen in line 3
da b4 28 fe 9e 4a 00 00 84 1a 8d 03 //third encryption done, same as above, decryption of null-bytes results in chaos, but original data still the same
48 61 6c 6c 6f 00 92 0f ae 88 98 be //last encryption, we got original data with some near random bytes
你可以看到第一个解密过程顺利进行,除了获得“解密”的3个填充字节外,也是第二个。因此,在每次加密过程之后,我们接近原始数据,但我们会保留解密这些填充字节。 (注意:如果有人怀疑我的加密/解密功能,我会对它们进行100次测试,并且每次都有效,我也可以在需要或怀疑时发布源代码)
将所有这些都放在一个简单的问题上,当我解密数据时,我怎么知道哪些空字节是原始数据的一部分,哪些是由加密算法添加的? 你有什么想法我能做到吗?
答案 0 :(得分:1)
您可以使用填充模式(例如PKCS#7)来填充填充字节本身的填充量,而不是对数据进行填充。这允许在解密时确定填充字节的数量,以便可以删除它们而只留下原始明文。
本质上,填充字节都是=添加的填充字节数。例如。如果需要3个填充字节,那么填充将是0x03
的3个字节。
始终至少有一个填充字节,这意味着如果明文已经是块大小的倍数,则必须添加仅由填充组成的附加块。这确保了可以区分明文块大小与块大小完全相同,已经以n
字节n
结束,明文已填充n
个字节。