2009-11-13 2 views
2

Я в основном пытаются сделать следующее на Java/JSP-ведомой веб-сайт:Как упаковать/зашифровать/распаковать/расшифровать кучу файлов в Java?

  • Пользователь поставляет пароль
  • Пароль используется для создания сильно зашифрованный файл архива (ZIP, или что-нибудь else), содержащий текстовый файл, а также несколько двоичных файлов, которые хранятся на сервере. Это, по сути, резервная копия файлов и настроек пользователя.
  • Позже пользователь может загрузить файл, предоставить исходный пароль, и сайт расшифрует и распакует архив, сохранит извлеченные двоичные файлы в соответствующую папку на сервере, а затем прочитает текстовый файл, чтобы сайт мог восстановить старые настройки пользователя и метаданные о двоичных файлах.

Это здание/шифрование архива, а затем извлечение его содержимого, которое я пытаюсь выяснить, как это сделать. Я действительно не забочусь о формате архива, кроме того, что он очень безопасен.

Идеальное решение для моей проблемы будет очень легко реализовать и потребует только проверенных и проверенных библиотек со свободными и неограничивающими лицензиями (например, apache, berkeley, lgpl).

Я знаю библиотеки TrueZIP и WinZipAES; первый кажется массивным излишеством, и я не могу сказать, насколько он стабилен ... Есть ли другие решения, которые будут работать хорошо?

ответ

6

Если вы знаете, как создать zip-файл с помощью пакета java.util.zip, вы можете создать PBE Cipher и передать его в CipherOutputStream или CipherInputStream (в зависимости от того, читаете или пишете).

Следующая должно вам начать работу:

public class ZipTest { 

    public static void main(String [] args) throws Exception { 
     String password = "password"; 
     write(password); 
     read(password); 
    } 

    private static void write(String password) throws Exception { 
     OutputStream target = new FileOutputStream("out.zip"); 
     target = new CipherOutputStream(target, createCipher(Cipher.ENCRYPT_MODE, password)); 
     ZipOutputStream output = new ZipOutputStream(target); 

     ZipEntry e = new ZipEntry("filename"); 
     output.putNextEntry(e); 
     output.write("helloWorld".getBytes()); 
     output.closeEntry(); 

     e = new ZipEntry("filename1"); 
     output.putNextEntry(e); 
     output.write("helloWorld1".getBytes()); 
     output.closeEntry(); 

     output.finish(); 
     output.flush(); 
    } 

    private static Cipher createCipher(int mode, String password) throws Exception { 
     String alg = "PBEWithSHA1AndDESede"; //BouncyCastle has better algorithms 
     PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); 
     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg); 
     SecretKey secretKey = keyFactory.generateSecret(keySpec); 

     Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede"); 
     cipher.init(mode, secretKey, new PBEParameterSpec("saltsalt".getBytes(), 2000)); 

     return cipher; 
    } 

    private static void read(String password) throws Exception { 
     InputStream target = new FileInputStream("out.zip"); 
     target = new CipherInputStream(target, createCipher(Cipher.DECRYPT_MODE, password)); 
     ZipInputStream input = new ZipInputStream(target); 
     ZipEntry entry = input.getNextEntry(); 
     while (entry != null) { 
      System.out.println("Entry: "+entry.getName()); 
      System.out.println("Contents: "+toString(input)); 
      input.closeEntry(); 
      entry = input.getNextEntry(); 
     } 
    } 

    private static String toString(InputStream input) throws Exception { 
     byte [] data = new byte[1024]; 
     StringBuilder result = new StringBuilder(); 

     int bytesRead = input.read(data); 
     while (bytesRead != -1) { 
      result.append(new String(data, 0, bytesRead)); 
      bytesRead = input.read(data); 
     } 

     return result.toString(); 
    } 
} 
+0

Какое программное обеспечение будет использовать клиент для дешифрования скремблированного ZIP-файла? –

+0

@PP Не думайте, что это можно будет сделать с этим решением, поскольку файл является просто зашифрованным блобом. ОП указал, что он хочет контролировать дешифрование/распаковку самостоятельно, а не стороннюю сторону. – Kevin

4

Ответ уже дан (использование шифра Кевин указал), так что я только делаю предложение о важном вопросе, который, кажется, не хватает в ваш topicstart: убедитесь, что вы используете HTTPS вместо HTTP. В противном случае один с сетевым сниффером сможет получить предоставленный пользователем пароль из пакетов. Как это сделать, зависит от рассматриваемого сервера приложений. Лучше всего ссылаться на свою документацию. Если это, например, Apache Tomcat, то вы можете найти все в Tomcat SSL HOW-TO.

Надеюсь, это поможет.

0

Возможно, это не относится к вашему запросу. Интересно, может ли truecrypt быть полезным. Ваш веб-сервер может создать зашифрованный контейнер, в который будет скопирован zip-файл. Зашифрованный контейнер затем можно загрузить. Потенциально немного беспорядочно, однако шифрование должно быть сильным, и загруженное изображение может быть смонтировано в различных операционных системах.

0

Здесь, конечно, есть несколько советов о том, как решить вашу проблему, но мне не хватает очень большого НО в ответах. Вы не можете выполнять как «основанное на пароле», так и «сильное шифрование» для любого разумного определения «сильного шифрования».

+0

Это необязательно.Если вы можете предоставить пароль, который дает вам 256 или даже 192 бита энтропии, вы можете подать это на любой подходящий блочный шифр. – Kevin

+0

Точно, «если вы можете ...», и в большинстве реальных ситуаций это непрактично. Оценки энтропии английского языка (как естественного) составляют всего 0,6 бит/символ, что означает, что вам понадобится фраза с длиной в 430 символов для 256 бит энтропии, и это немного больше, чем я обычно понимаю как пароль. – jarnbjo

+0

Ну, конечно, если вы позволите людям использовать английские слова в качестве паролей. Просто поставьте некоторые простые ограничения - например. требуется хотя бы одна заглавная буква и один специальный символ - и вы получаете много энтропии. – DanM

Смежные вопросы