Chacha20-poly1305: не потоковой?JAVA

Программисты JAVA общаются здесь
Anonymous
Chacha20-poly1305: не потоковой?

Сообщение Anonymous »

выпуск < /h2>
Дешиптер Chacha20-poly1305, встроенный в современные JDK от поставщика по умолчанию, по-видимому, подходит только для тривиальных сценариев тестирования. Конкретная проблема заключается в том, что он не может транслировать: он должен нагрузить каждый расшифрованное байт в память и не возвращает ни одного из них, пока вы не закончите все дешифрование, после чего он даст вам каждый байт. Я утверждаю, что это по сути бесполезно/академическое, поскольку это означает, что вы не можете расшифровать какие -либо зашифрованные данные Chacha20, если они не достаточно малы, чтобы удерживать весь контент в памяти. Примечательно, что шифрование < /em> не страдает от этого довольно странного надзора. Возможно, это не то, для чего является Chacha20 -Poly1305, как chacha20 сама по себе без Poly1305 can потоковых данных во время расшифровки. Doupdate () Метод иннобрированного класса EngineAeaddec ничего не делает, кроме содержания спама во внутренний байтовый буфер. Единственные пути возврата, которые у него есть, и тривиальный взгляд на источник, по -видимому, подтверждает это, либо исключение, либо возврат 0; , указывающий, что байты не были переданы в выходной буфер. (Строка 1587 В текущей версии источника).
В отличие от этого, один и тот же метод во внутреннем классе engineaeadenc (строка 1458 в текущей версии) показывает, что это doupdate может и фактически потоковые данные вместо того, чтобы засунуть все в конечный растущий bytearrayoutput
Как это крипто, это немного вовлечено. это совсем не безопасно, в частности, ключ и поколение, не подходящее! Даже не используйте его как вдохновение, это не то, о чем этот вопрос.

Код: Выделить всё

import java.nio.ByteBuffer;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class WhatAmIMissing {
public static void main(String[] args) throws Exception {
test(5000);
test(500_000);
}

private static void test(int dataSize) throws Exception {
System.out.println(" ---- TEST CASE: " + dataSize);
byte[] secret = new byte[32];
Arrays.fill(secret, (byte) 1); // This is obviously a silly and insecure key.
byte[] nonce = new byte[12];
Arrays.fill(nonce, (byte) 2); // Same.
SecretKey key = new SecretKeySpec(secret, "ChaCha20");
Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305");
System.out.println("CCP provider: " + cipher.getProvider().getInfo());
IvParameterSpec spec = new IvParameterSpec(nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);

ByteBuffer allData = ByteBuffer.allocate(dataSize);
// Fill with arbitrary data. We want to encrypt all of this data.
for (int i = 0; i < allData.capacity(); i++) allData.put(i, (byte) i);

ByteBuffer result = ByteBuffer.allocate(dataSize + 65536);

ByteBuffer from = ByteBuffer.allocate(32768);
ByteBuffer to = ByteBuffer.allocate(65536);

while (allData.hasRemaining()) {
int transfer = Math.min(from.remaining(), allData.remaining());
allData.limit(allData.position() + transfer);
from.put(allData);
allData.limit(allData.capacity());
from.flip();
int written = cipher.update(from, to);
System.out.println("Written: " + written);
from.compact();
to.flip();
result.put(to);
to.clear();
}
from.position(from.limit());
System.out.println("Written: " + cipher.doFinal(from, to));
to.flip();
result.put(to);

System.out.println("Encryption complete.  Resulting size: " + result.position());

result.flip();
to.clear();
from.clear();
allData.clear();

// Now we do the same thing in reverse.
cipher = Cipher.getInstance("ChaCha20-Poly1305");
cipher.init(Cipher.DECRYPT_MODE, key, spec);
while (result.hasRemaining()) {
int transfer = Math.min(from.remaining(), result.remaining());
int lim = result.limit();
result.limit(result.position() + transfer);
from.put(result);
result.limit(lim);
from.flip();
int fromRemaining = from.remaining();
int written = cipher.update(from, to);
System.out.println("Written: " + written + " Read: " + (fromRemaining - from.remaining()));
from.compact();
to.flip();
allData.put(to);
to.clear();
}
from.position(from.limit());
System.out.println("Written: " + cipher.doFinal(from, to));
to.flip();
allData.put(to);

System.out.println("Decryption complete. Resulting size: " + allData.position());

// Confirm the encryption/decryption process resulted in the same data
for (int i = 0; i < allData.capacity(); i++) if (allData.get(i) != (byte) i) {
System.out.println("!!!! Mismatch!");
break;
}
System.out.println("Matches");
}
}
Запуск вышеупомянутого кода достигает успеха для первого тестового примера (потому что буферы, используемые для «процесса», могут содержать полные данные), но сбои для второго. /> размышления < /h2>
Возможно, шифр «сдерживает все данные, потому что он не может проверить часть Poly1305 до самого конца. Тем не менее, я хочу для вызова Dofinal , а затем бросить. Другими словами, если, например, Получение потока из 10 ГБ зашифровала данные по сети и написание его на диск, чтобы написать почти 10 ГБ на диск, чтобы затем получить исключение, указывающее: «Неужели, ни один из них не подлежит полезным», в этот момент файл (который создается с именем заполнителя и еще не перенесен на место) просто будет удален. Есть ли какой-нибудь альтернативный chacha20-poly1305, который может сделать это? AES512 и используйте это, но это похоже на бессмысленные дополнительные шаги (в полной настройке мы будем использовать что-то вроде ML-KEM или ED25519, чтобы генерировать секрет, этот секрет затем используется для генерации еще одного секрета с Chacha20-poly1305 .. который кажется бессмысленным, почему бы не использовать ML-Kem Please непосредственно в качестве ключа для aeS. /> Основная задача < /h2>
Я бы хотел выполнить следующую операцию: < /p>

Администратор генерирует пару ключей ML-KEM, надежно хранит подключенный к ключам, и загружает большие данные. «BackupServer». Резервное копирование должно быть безопасным: как перевод, так и резервное копирование в состоянии покоя должны быть зашифрованы таким образом, чтобы ни «веб -сервер», ни «резервный сервер» не должны быть способны расшифровать эти данные (например, если они скомпрометированы, это не имеет значения). Конечно, в какой -то момент «WebServer» есть незашифрованные данные, но каких -либо данных, которые больше не находятся в его банках памяти или на дисковых секторах, не могут быть восстановлены злонамеренным актером, даже если они укоренились либо «WebServer», либо «BackupServer» или обоих. Для этого «WebServer» использует ML-Kem для генерации инкапсулированного секрета. Затем он посылает инкапсулированный секрет вместе с зашифрованными данными (потоковой передачей, как и 10 ГБ) с этой секретом, используя Chacha20-Poly1305 для «резервного органа», который покорно хранит это на своем диске. (Упрощенный: применяется Рид-Соломон, с CRCS и хешоном, чтобы обеспечить защиту от битовых переворот и коррупции, но это, вероятно, не имеет отношения к этому вопросу). Затем этот ключ можно использовать для установки шифра Chacha20-Poly1305 в режиме расшифровки, дешифруя остальную часть файла. Проблема в том, что это не работает, если у машины не менее 10 ГБ на самом деле дешифтируют его, поскольку все хранится в RAM. < /Li>
< /ul>
Вопросы < /h2>

Является ли вышеуказанный протокол подходящим применением chacha20-poly1305? Неспособен к потоковой передаче? Просто «написано дураком /написанным кем -то, кто не рассматривал эти ограничения /API», или есть более информативная причина? < /Li>
Если да, то какой альтернативный поставщик имеет лучшую реализацию? Используйте AES-512/GCM?

Код: Выделить всё

Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305", new org.bouncycastle.jce.provider.BouncyCastleProvider());
// instead of just Cipher.getInstance("ChaCha20-Poly1305");
// requires on the classpath: bcprov-jdk18on.jar
приводит к успешному тесту, предполагая, что, возможно, объяснение может быть «инженером OpenJDK, испорченным», и должна быть подана ошибка, но, скорее всего, я не буду кое-что в природе Chacha20-poly1305.

Подробнее здесь: https://stackoverflow.com/questions/797 ... streamable

Вернуться в «JAVA»