我已经实现了 AES 加密(作业),但我偶然发现了填充消息的问题。
如果我的消息是这样的字节数组:
public byte[] encrypt(byte[] message) {
int size = (int) Math.ceil(message.length / 16.0);
byte[] result = new byte[size * 16];
for (int i = 0; i < size; i++) {
if ((i+1) * 16 > message.length){
//padding here????
} else {
byte[] block = Arrays.copyOfRange(message, i * 16, (i + 1) * 16);
byte[] encryptedBlock = encryptBlock(block);
System.arraycopy(encryptedBlock, 0, result, i*16, 16);
}
}
return result;
}
我怎样才能填充这样的消息?
我无法使用零填充,因为每个字节都可能为零,并且它可能会影响带有尾随零的此类消息。
我找不到任何关于这是如何完成的参考here http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf(描述AES加密的论文)
您可以使用多种方法,从简单到高级。 Bruce Schneier 建议两种相当简单的方法:
一种是用 n 个字节填充最后一个块,所有字节的值均为 n,这是 Alex Wien 所建议的。这存在问题(包括限制块大小小于 256 字节长)。这种填充模式称为 PKCS#7 填充(对于 16 字节块)或 PKCS#5 填充(对于 8 字节块)。
另一种方法是附加一个值为 0x80 的字节(二进制值为 1000 0000 的字节),后跟填充最后一个块所需的多个零字节。这种方法称为 ISO 填充,是 ISO/IEC 9797-1 填充方法 2 的缩写。填充本身是位级填充,添加值为 1 的单个位,然后添加值为 0 的位,直到到达块尺寸。
至于如何知道一条消息是否被填充,答案是消息会always填充:即使消息的最后一个块完全适合块内(即消息的大小是块大小的倍数),您也必须添加一个虚拟的最后一个块。
如果您有兴趣研究一些更高级的方法,请在维基百科上查找一种称为密文窃取的技术:http://en.wikipedia.org/wiki/Ciphertext_stealing http://en.wikipedia.org/wiki/Ciphertext_stealing
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)