1

I am trying to encrypt a file(txt, pdf, doc) using Google Tink - streaming AEAD encryption, below is the Java code which I am trying to execute. But all I get is 1 KB output encrypted file and no errors. All Input files whether 2 MB or more than 10 MB, output file will be always of 1 KB. I am unable to figure out what could be going wrong, can someone please help.

      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()` : always provide a chararacter set, you never know which runtime your code will appear. Specify `StandardCharsets.UTF_8` to make absolutely sure that one luckless developer in the future sees an unexplained authentication failure appear out of thin air. – Maarten Bodewes Feb 03 '20 at 14:01
  • I will keep this in mind, thanks for the suggestion. – hoch_london Feb 03 '20 at 21:30
  • https://github.com/google/tink/blob/4cc630dfc711555f6bbbad64f8c573b39b7af500/examples/java_src/streamingaead/StreamingAeadExample.java – ecle Dec 05 '21 at 07:43

1 Answers1

1

This is all about understanding ByteBuffer and how it operates. Let me explain.

in.read(buffer.array());

This writes data to the underlying array, but since array is decoupled from the state of the original buffer, the position of the buffer is not advanced. This is not good, as the next call:

encryptingChannel.write(buffer);

will now think that the position is 0. The limit hasn't changed either and is therefore still set to the capacity: 256. That means the result of the write operation is to write 256 bytes and set the position to the limit (the position).

Now the read operation still operates on the underlying byte array, and that's still 256 bytes in size. So all next read operations take place perfectly. However, all the write operations will assume that there are no bytes to be written, as the position remains at 256.

To use ByteBuffer you can use FileBuffer.read. Then you need to flip the buffer before writing the read data. Finally, after writing you need to clear the buffer's position (and limit, but that only changes on the last read) to prepare the buffer for the next read operation. So the order is commonly read, flip, write, clear for instances of Buffer.

Don't mix Channels and I/O streams, it will makes your life unnecessarily complicated, and learning how to use ByteBuffer is hard enough all by itself.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks a lot Maarten, I was thinking that the error has to do something with Byte reading and writing. I will spend some time now in mastering this before commencing further. Many thanks for commenting. – hoch_london Feb 03 '20 at 21:28
  • Sure thing. Don't forget to accept answers if they solve your problem! Best way to say thank you (besides upvoting, but that's 15 rep & higher). – Maarten Bodewes Feb 03 '20 at 21:53
  • Because I am less than 15 rep, it does not allow me but records my upvoting. Can I ask you for an example/links of tutorial where file based encryption is being done in java and most importantly is secure. – hoch_london Feb 04 '20 at 09:56
  • No, you'll have to try yourself. I've given you a valid answer, but I don't think I'm obliged to code for you. I have issues with posting full "file encryption" code because I think there is too much copy / paste of crypto code going on. Each use case should be considered separately. – Maarten Bodewes Feb 04 '20 at 13:05
  • I was not asking for full fledge code but a tutorial link, it is ok I will google it. – hoch_london Feb 04 '20 at 15:08