谷歌TINK - 流式AEAD 始终返回 1 KB 的输出文件



我正在尝试使用Google Tink加密加密文件(txt,pdf,doc( - 流式AEAD加密,以下是我正在尝试执行的Java代码。但我得到的只是 1 KB 输出加密文件,没有错误。所有输入文件无论是 2 MB 还是大于 10 MB,输出文件将始终为 1 KB。 我无法弄清楚可能出了什么问题,有人可以帮忙吗?

TinkConfig.register();
final int chunkSize = 256;
KeysetHandle keysetHandle = KeysetHandle.generateNew(               
StreamingAeadKeyTemplates.AES128_CTR_HMAC_SHA256_4KB);
// 2. Get the primitive.
StreamingAead streamingAead = keysetHandle.getPrimitive(StreamingAead.class);
// 3. Use the primitive to encrypt some data and write the ciphertext to a file,
FileChannel ciphertextDestination =
new FileOutputStream("encyptedOutput.txt").getChannel();
String associatedData = "Tinks34";
WritableByteChannel encryptingChannel =
streamingAead.newEncryptingChannel(ciphertextDestination, associatedData.getBytes());
ByteBuffer buffer = ByteBuffer.allocate(chunkSize);
InputStream in = new FileInputStream("FileToEncrypt.txt");
while (in.available() > 0) {
in.read(buffer.array());
System.out.println(in);
encryptingChannel.write(buffer);
}
encryptingChannel.close();
in.close();
System.out.println("completed");

这完全是关于理解ByteBuffer及其运作方式。让我解释一下。

in.read(buffer.array());

这会将数据写入基础数组,但由于数组与原始缓冲区的状态分离,因此缓冲区的位置不提前。这不好,因为下一个调用:

encryptingChannel.write(buffer);

现在会认为该位置为 0。限制也没有改变,因此仍设置为容量:256。这意味着写入操作的结果是写入 256 个字节并将位置设置为限制(位置(。

现在,读取操作仍在底层字节数组上运行,大小仍为 256 字节。因此,所有后续读取操作都将完美进行。但是,所有写入操作都将假定没有要写入的字节,因为位置保持在 256。

要使用ByteBuffer您可以使用FileBuffer.read.然后,您需要在写入读取数据之前flip缓冲区。最后,写入后,您需要clear缓冲区的位置(和限制,但仅在上次读取时更改(,以便为下一次读取操作准备缓冲区。所以顺序通常是读、翻、写,对于Buffer的实例来说很清楚。

不要混合Channel和I/O流,这会让你的生活变得不必要的复杂,学习如何使用ByteBuffer本身就已经够难的了。

最新更新