Быстрое модульное добавление 2 (потенциально больших) файлов в java

#java #performance #cryptography #nio

#java #Производительность #криптография #nio

Вопрос:

Я провожу эксперимент по криптографии с одноразовыми пэдами.

У меня есть два файла OTP и TEXT (1K-10K) с байтами в них. OTP имеет большой размер (> 1 ГБ). Я хочу создать третий файл CYPHERTEXT (того же размера, что и ТЕКСТ), выполнив модульное добавление ТЕКСТА с помощью OTP, используя смещение в OTP. Я закодировал это вручную, используя java.io , и это работает, но не очень быстро, даже с буферизованным вводом-выводом (потоки или записи).

Я искал способ добавить один из базовых байтовых буферов вместе с другим, используя NIO, но не смог найти (встроенный) способ сделать это или отфильтровать содержимое ТЕКСТА с использованием данных из OTP, кроме как вручную. Есть ли какой-нибудь способ сделать что-то подобное, не изобретая велосипед? Я подумал, что мог бы использовать селектор. В идеале я хотел бы иметь возможность обрабатывать файлы размером более 2 ГБ как для OTP, так и для ТЕКСТА, поэтому я смотрел на NIO.

 private static void createOTP() {
...
System.out.print("Generating "   filename   " ");
long startTime = System.nanoTime();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos, MB);
for(long currentSize =0; currentSize < OTPSize; currentSize  = baSize){
   new SecureRandom().nextBytes(ba);
   bos.write(ba);
   if(currentSize % (MB * 20L * (long)sizeInGB)==0){
      System.out.print(".");
   }
}
long elapsedTime = System.nanoTime() - startTime;
System.out.println(" OTP generation elapsed Time is "   (elapsedTime / 1000000.0)   " msec");
fos.close();
bos.close();
...
}

private static void symetricEncryptionDecryption(boolean encrypt) { 
...
outtext=new File(intext.getParentFile(), direction   ".OTP");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outtext), MB);
byte[] plaindata = new byte[(int)intext.length()];
DataInputStream dataIs = new DataInputStream(new FileInputStream(intext));
dataIs.readFully(plaindata);
dataIs.close();
ByteBuffer bb = ByteBuffer.wrap(plaindata);
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(otpFile))); 
in.skip(offset);
while(bb.hasRemaining()){
    bos.write( bb.get()   (encrypt? in.readByte() : -in.readByte()) );
}
bos.close();
in.close();
System.out.println("Offset: "   offset);
}
  

Итак, есть ли более простой способ сделать это:

 while(bb.hasRemaining()){
    bos.write( bb.get()   (encrypt? in.readByte() : -in.readByte()) );
}
  

Или для генерации OTP, если на то пошло.

Комментарии:

1. Я предлагаю вам уточнить, что вы имеете в виду. файл размером 1 ГБ является большим, поэтому для его обработки и чтения / записи потребуется время. Вы не сказали, какой у вас диск, и это, вероятно, будет иметь решающее значение для того, как быстро вы сможете это сделать, то, что вы делаете на Java, вероятно, будет важным. Поток может быть любой длины, поэтому вы можете использовать обычный ввод-вывод, а также NIO. Неясно, что вы делаете, но если вы читаете / обрабатываете 8 байтов за раз, например, длинный, вы, вероятно, будете достаточно быстрыми.

2. Я добавил пример кода. 1 ГБ — это небольшой OTP для этих целей. Поэтому было бы неплохо, чтобы данные, которые я шифрую, были любого размера, в том числе превышали предельный размер 2 ГБ. Все это происходит на обычном жестком диске IDE со скоростью 7200 об / мин или, возможно, на диске USB 3.0.

3. Где int применяется ограничение? Кстати, ничто не мешает вам постепенно читать ТЕКСТОВЫЙ файл так же, как вы постепенно читаете OTP-файл. Вы должны быть в состоянии прочитать / записать файл размером 1 МБ менее чем за 0,1 секунды.

4. Кстати, если вы используете ^ побитовый XOR, вы можете применять его как для кодирования, так и для декодирования, и вы можете применять его по N байтов за раз, например, по 8 байтов за раз, вместо одного байта за раз.

5. Намеренное создание OTP будет дорогостоящим. Вы могли бы сгенерировать файл гораздо меньшего размера. т. Е. Только такого размера, какой вам нужен, и использовать менее дорогой генератор случайных чисел.

Ответ №1:

Неясно, что вы пытаетесь сделать, но если вы сопоставляете файл OTP с памятью, предоставляя вам произвольный доступ, и вы читаете / обрабатываете 8 байтов за раз, т.Е. long Значения, Вы должны иметь возможность записать зашифрованный текстовый файл размером 10 КБ менее 100 мс, где большая часть этого времени будет потрачена на запуск JVM.

Кстати: если у вас есть доступ к зашифрованному тексту и файлу OTP, вы можете декодировать текст без смещения, т.Е. Вы можете обработать его с помощью грубой силы.

Комментарии:

1. Схема основана на том, что OTP никогда не используется повторно, и на безопасном депонировании ключей. Тогда проблема становится просто распределением ключей. «Если ключ действительно случайный и, по крайней мере, такой же длины, как открытый текст, и никогда не используется повторно полностью или частично, и хранится в полном секрете, то полученный зашифрованный текст будет невозможно расшифровать или взломать.[1][2]»<википедия>

2. @GGB667 Это то, что я подумал.

3. Из-за постоянной передачи шума только лицо, получающее данные, у которого уже был OTP, могло знать, передавалось ли сообщение вообще. Если уровень шума достаточен, а скорость преобразования шума в сигнал достаточно высока, злоумышленнику придется хранить ВСЕ переданные данные, если они впоследствии завладеют ключом, чтобы найти отправленные сообщения. Я использую OTP только тогда, когда я действительно отправляю сообщение. Если шум случайно задерживается перед передачей, чтобы помешать анализу синхронизации, будет работать только захват OTP и запись всех данных.

4. @GGB667 Вы пытаетесь сделать что-то невозможное для взлома, более невозможное?

5. Это не невозможно сломать. Злоумышленникам просто нужно получить одноразовую панель. Затем они могут читать все, что когда-либо отправлялось. Если только они не могут хранить все, что вы (и 2 миллиарда других вещей, использующих эту схему шифрования) уже отправили. Это позволило бы правительству нацеливаться на конкретных преступников или террористов и людей, с которыми они общаются, но не на весь мир