Как упаковать/зашифровать/распаковать/расшифровать кучу файлов в Java?
-
20-09-2019 - |
Вопрос
По сути, я пытаюсь сделать следующее на веб-сайте, управляемом Java/JSP:
- Пользователь вводит пароль
- Пароль используется для создания сильно зашифрованного архивного файла (zip или чего-либо еще), содержащего текстовый файл, а также ряд двоичных файлов, хранящихся на сервере.По сути, это резервная копия файлов и настроек пользователя.
- Позже пользователь может загрузить файл, указать исходный пароль, и сайт расшифрует и распакует архив, сохранит извлеченные двоичные файлы в соответствующую папку на сервере, а затем прочитает текстовый файл, чтобы сайт мог восстановить пароль пользователя. старые настройки и метаданные о двоичных файлах.
Я пытаюсь понять, как это сделать: создать/зашифровать архив, а затем извлечь его содержимое.Меня действительно не волнует формат архива, кроме того, что он очень безопасен.
Идеальное решение моей проблемы будет очень простым в реализации и потребует только проверенных библиотек со свободными и неограниченными лицензиями (например,Apache, Беркли, LGPL).
Мне известны библиотеки TrueZIP и WinZipAES;первое кажется излишним, и я не могу сказать, насколько стабильно второе...Есть ли другие решения, которые будут работать хорошо?
Решение
Если вы знаете, как создать zip-файл с помощью java.util.zip пакет, вы можете создать PBE Шифр и передайте его в 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();
}
}
Другие советы
Ответ уже дан (используйте шифр, как указал Кевин), поэтому я всего лишь предлагаю по важному вопросу, который, похоже, отсутствует в начале вашей темы:убедитесь, что вы используете HTTPS
вместо HTTP
.В противном случае тот, у кого есть сетевой анализатор, сможет получить пароль, введенный пользователем, из пакетов.Как это сделать, зависит от рассматриваемого сервера приложений.Лучше всего обратиться к его документации.Если это например Apache Tomcat, то все можно найти в Tomcat SSL: Практическое руководство.
Надеюсь это поможет.
Хотя это может не относиться к вашему запросу, мне интересно, истинный крипт может оказаться полезным.Ваш веб-сервер может создать зашифрованный контейнер, в который будет скопирован zip-файл.Зашифрованный контейнер затем можно было загрузить.Потенциально это немного запутанно, однако шифрование должно быть надежным, и загруженный образ можно будет смонтировать в различных операционных системах.
Здесь наверняка есть несколько предложений, как решить вашу проблему, но мне не хватает очень большого НО в ответах.Вы не можете выполнить одновременно «надежное шифрование» и «надежное шифрование» для любого разумного определения «надежного шифрования».