Google TINK - Streaming AEAD Всегда возвращает выходной файл размером 1 КБ - PullRequest
1 голос
/ 02 февраля 2020

Я пытаюсь зашифровать файл (txt, pdf, do c), используя Google Tink - потоковое шифрование AEAD, ниже приведен код Java, который я пытаюсь выполнить. Но все, что я получаю, это зашифрованный файл размером 1 Кбайт и без ошибок. Все входные файлы, будь то 2 МБ или более 10 МБ, выходной файл всегда будет иметь размер 1 КБ. Я не могу понять, что может быть не так, может кто-то, пожалуйста, помогите.

      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");

1 Ответ

0 голосов
/ 03 февраля 2020

Это все о понимании ByteBuffer и о том, как оно работает. Позвольте мне объяснить.

in.read(buffer.array());

Это записывает данные в базовый массив, но так как массив отделен от состояния исходного буфера, позиция буфер не расширен Это не хорошо, так как следующий вызов:

encryptingChannel.write(buffer);

теперь будет думать, что позиция равна 0. Ограничение также не изменилось и поэтому по-прежнему установлен на емкость : 256. Это означает, что результатом операции записи является запись 256 байтов и установка позиции в пределе (позиция).

Теперь операция чтения по-прежнему работает с базовым байтовым массивом, и его размер все еще составляет 256 байтов Таким образом, все последующие операции чтения происходят идеально. Однако все операции записи предполагают, что байтов для записи не существует, так как позиция остается на 256.

Для использования ByteBuffer вы можете использовать FileBuffer.read . Затем вам нужно flip в буфер перед записью прочитанных данных. Наконец, после записи вам нужно clear положение буфера (и ограничение, но оно изменяется только при последнем чтении), чтобы подготовить буфер для следующей операции чтения. Так что порядок обычно : чтение, отражение, запись, очистка для экземпляров Buffer.

Не смешивайте Channel s и потоки ввода / вывода, это сделает вашу жизнь излишне сложный, и научиться использовать ByteBuffer достаточно сложно само по себе.

...