【问题标题】:Google TINK - Streaming AEAD Always returning an output file of 1 KBGoogle TINK - 流式传输 AEAD 始终返回 1 KB 的输出文件
【发布时间】:2020-02-02 18:48:04
【问题描述】:

我正在尝试使用 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");

【问题讨论】:

  • associatedData.getBytes() :总是提供一个字符集,你永远不知道你的代码会出现在哪个运行时。指定StandardCharsets.UTF_8 以绝对确保将来一位不幸的开发人员会看到不明原因的身份验证失败凭空出现。
  • 我会记住这一点,谢谢你的建议。

标签: java cryptography tink


【解决方案1】:

这一切都是为了了解ByteBuffer 及其运作方式。让我解释一下。

in.read(buffer.array());

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

encryptingChannel.write(buffer);

现在会认为 position 为 0。limit 也没有改变,因此仍设置为 capacity:256 .也就是说写操作的结果是写了256个字节,并将位置设置为限制(位置)。

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

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

不要将Channels 和 I/O 流混在一起,这会使你的生活变得不必要地复杂,而学习如何使用 ByteBuffer 本身就已经够难了。

【讨论】:

  • 非常感谢 Maarten,我认为该错误与字节读取和写入有关。在进一步开始之前,我现在将花一些时间来掌握这一点。非常感谢您的评论。
  • 当然。如果他们解决了您的问题,请不要忘记接受答案!表示感谢的最佳方式(除了支持,但那是 15 代表及更高)。
  • 因为我不到 15 个代表,所以它不允许我,但会记录我的点赞。我可以问你一个示例/教程链接,其中基于文件的加密是在 java 中完成的,最重要的是是安全的。
  • 不,您必须自己尝试。我给了你一个有效的答案,但我认为我没有义务为你编码。我在发布完整的“文件加密”代码时遇到问题,因为我认为加密代码的复制/粘贴太多。每个用例都应单独考虑。
  • 我不是要求完整的代码,而是一个教程链接,没关系,我会谷歌它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 2013-05-07
  • 2010-09-23
  • 2013-08-11
相关资源
最近更新 更多