Java:将ASCII 0(NULL)的字符串填充为16个字节的倍数

时间:2017-01-26 20:33:40

标签: java encryption padding

java中将空填充添加到字符串末尾的最简单方法是什么?这是加密过程的前一步,因此结果字符串必须是16字节的倍数。

首次尝试只是添加一个包含null的字符串的字符串1。但这并不起作用,因为null变成了单词' null'。

第二次尝试: 将字符串转换为字节,并以某种方式附加空字节,但我无法想出一种方法来使其工作。

第三次尝试: 初始化一个已知大的字节数组,如128减去字符串中的字节长度,然后将我的字符串转换为字节,将两个数组复制在一起。如下所示:

String stringToEncrypt = "some data" ;
byte[] stringToEncryptBytes = stringToEncrypt.getBytes("UTF-8");
int stringToEncryptByteLength = stringToEncryptBytes.length;

int sizeOfNullArray = 128 - stringToEncryptByteLength;
byte[] byteBlockOfNulls = new byte[sizeOfNullArray] ;

byte[] finalBytes = new byte[stringToEncryptByteLength + sizeOfNullArray];
System.arraycopy(stringToEncryptBytes, 0, finalBytes, 0, stringToEncryptByteLength); 
System.arraycopy(byteBlockOfNulls, 0, finalBytes, stringToEncryptByteLength, sizeOfNullArray);

但是当我将字节数组转换回字符串时,它只是乱码。所以我一定做错了。

1 个答案:

答案 0 :(得分:0)

当您说"这是加密过程中的前一步",您是在谈论填充要加密以达到块边界的明文,还是键拉伸以形成适当长度的键? "空填充"两者都不理想,但在关键推导中它是完全危险的。

如果您的问题是前者,您可能希望使用PKCS7Padding(在Java中也称为PKCS5Padding),works in the following manner

  • 如果消息长度小于完整块边界(即lengthBytes % 16 != 0),则最后一个块用 N 字节填充,其中 N = { {1}},每个字节的值为 N 。例如,如果最后一个块是13个字节,则将使用16 - (lengthBytes % 16)填充,以达到16的长度。
  • 如果消息长度是块大小的精确倍数(即0x03 0x03 0x03),则会添加lengthBytes % 16 == 0的完整块(16字节)。

上面的链接解释了完整的理由。出于多种原因,不建议使用零填充/空填充方案。

如果这实际上是关于如何实现练习代码的问题,则以下方法有效(在单个块上操作,而不是完整的明文):

0x10

如果转换回String,结果字节数组将如下所示。

String plaintext = "This is text"; // 12 bytes
byte[] plainBytes = plaintext.getBytes(StandardCharsets.UTF_8);
byte[] paddedBytes = new byte[16];
System.arraycopy(plainBytes, 0, paddedBytes, 0, plainBytes.length);

assert paddedBytes.length == 16;
assert paddedBytes[12] == (byte) 0x00;
assert paddedBytes[13] == (byte) 0x00;
assert paddedBytes[14] == (byte) 0x00;
assert paddedBytes[15] == (byte) 0x00;