Защищенный паролем zip файл в java
Я создал zip файл, используя java, как показано ниже.
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample {
public static void main(String[] args) throws IOException {
System.out.print("Please enter file name to zip : ");
BufferedReader input = new BufferedReader
(new InputStreamReader(System.in));
String filesToZip = input.readLine();
File f = new File(filesToZip);
if(!f.exists()) {
System.out.println("File not found.");
System.exit(0);
}
System.out.print("Please enter zip file name : ");
String zipFileName = input.readLine();
if (!zipFileName.endsWith(".zip"))
zipFileName = zipFileName + ".zip";
byte[] buffer = new byte[18024];
try {
ZipOutputStream out = new ZipOutputStream
(new FileOutputStream(zipFileName));
out.setLevel(Deflater.DEFAULT_COMPRESSION);
FileInputStream in = new FileInputStream(filesToZip);
out.putNextEntry(new ZipEntry(filesToZip));
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
out.close();
} catch (IllegalArgumentException iae) {
iae.printStackTrace();
System.exit(0);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
System.exit(0);
} catch (IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
}
}
Теперь, когда я нажимаю на zip файл, он должен пригласить меня ввести пароль, а затем распаковать zip файл.
Пожалуйста, помогите, как мне идти дальше?
Ответы
Ответ 1
Стандартный Java API не поддерживает защищенные паролем ZIP файлы. К счастью, хорошие ребята уже реализовали такую возможность для нас. Пожалуйста, взгляните на эту статью, в которой объясняется, как создать защищенный паролем zip: http://java.sys-con.com/node/1258827
Ответ 2
Ниже приведен пример кода zip и пароль для защиты вашего файла.
Эта служба REST принимает байты исходного файла. Он застегивает массив байтов, и пароль защищает его. Затем он отправляет байты защищенного паролем zip файла в качестве ответа. Код представляет собой образец отправки и получения двоичных байтов в и из службы REST, а также для архивирования файла с защитой паролем. Байты заархивированы из потока, поэтому на сервере никогда не хранятся файлы.
- Использует API JAX-RS с использованием API Джерси в java
- Клиент использует API-интерфейс Jersey-client.
- Использует zip4j 1.3.2 библиотеку с открытым исходным кодом и apache commons io.
@PUT
@Path("/bindata/protect/qparam")
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response zipFileUsingPassProtect(byte[] fileBytes, @QueryParam(value = "pass") String pass,
@QueryParam(value = "inputFileName") String inputFileName) {
System.out.println("====2001==== Entering zipFileUsingPassProtect");
System.out.println("fileBytes size = " + fileBytes.length);
System.out.println("password = " + pass);
System.out.println("inputFileName = " + inputFileName);
byte b[] = null;
try {
b = zipFileProtected(fileBytes, inputFileName, pass);
} catch (IOException e) {
e.printStackTrace();
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
System.out.println(" ");
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println(" ");
return Response.ok(b, MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition", "attachment; filename = " + inputFileName + ".zip").build();
}
private byte[] zipFileProtected(byte[] fileBytes, String fileName, String pass) throws IOException {
ByteArrayInputStream inputByteStream = null;
ByteArrayOutputStream outputByteStream = null;
net.lingala.zip4j.io.ZipOutputStream outputZipStream = null;
try {
//write the zip bytes to a byte array
outputByteStream = new ByteArrayOutputStream();
outputZipStream = new net.lingala.zip4j.io.ZipOutputStream(outputByteStream);
//input byte stream to read the input bytes
inputByteStream = new ByteArrayInputStream(fileBytes);
//init the zip parameters
ZipParameters zipParams = new ZipParameters();
zipParams.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipParams.setEncryptFiles(true);
zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
zipParams.setPassword(pass);
zipParams.setSourceExternalStream(true);
zipParams.setFileNameInZip(fileName);
//create zip entry
outputZipStream.putNextEntry(new File(fileName), zipParams);
IOUtils.copy(inputByteStream, outputZipStream);
outputZipStream.closeEntry();
//finish up
outputZipStream.finish();
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
return outputByteStream.toByteArray();
} catch (ZipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
}
return null;
}
Unit test ниже:
@Test
public void testPassProtectZip_with_params() {
byte[] inputBytes = null;
try {
inputBytes = FileUtils.readFileToByteArray(new File(inputFilePath));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("bytes read into array. size = " + inputBytes.length);
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080").path("filezip/services/zip/bindata/protect/qparam");
target = target.queryParam("pass", "mypass123");
target = target.queryParam("inputFileName", "any_name_here.pdf");
Invocation.Builder builder = target.request(MediaType.APPLICATION_OCTET_STREAM);
Response resp = builder.put(Entity.entity(inputBytes, MediaType.APPLICATION_OCTET_STREAM));
System.out.println("response = " + resp.getStatus());
Assert.assertEquals(Status.OK.getStatusCode(), resp.getStatus());
byte[] zipBytes = resp.readEntity(byte[].class);
try {
FileUtils.writeByteArrayToFile(new File(responseFilePathPasswordZipParam), zipBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
Не стесняйтесь использовать и изменять. Пожалуйста, дайте мне знать, если вы найдете какие-либо ошибки. Надеюсь это поможет.
Изменить 1 - Использовать QueryParam, но вместо этого вы можете использовать HeaderParam для PUT, чтобы скрыть passwd с простого вида. Измените метод теста соответствующим образом.
Изменить 2 - путь REST - filezip/services/zip/bindata/protect/qparam
filezip - это название войны. services - это URL-адрес в web.xml. zip - это аннотация для дорожки уровня класса. bindata/protect/qparam - это аннотация метода пути уровня метода.
Ответ 3
Попробуйте использовать следующий код, основанный на Zip4j
:
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
public class Zipper
{
private String password;
private static final String EXTENSION = "zip";
public Zipper(String password)
{
this.password = password;
}
public void pack(String filePath) throws ZipException
{
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_ULTRA);
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
zipParameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
zipParameters.setPassword(password);
String baseFileName = FilenameUtils.getBaseName(filePath);
String destinationZipFilePath = baseFileName + "." + EXTENSION;
ZipFile zipFile = new ZipFile(destinationZipFilePath);
zipFile.addFile(new File(filePath), zipParameters);
}
public void unpack(String sourceZipFilePath, String extractedZipFilePath) throws ZipException
{
ZipFile zipFile = new ZipFile(sourceZipFilePath + "." + EXTENSION);
if (zipFile.isEncrypted())
{
zipFile.setPassword(password);
}
zipFile.extractAll(extractedZipFilePath);
}
}
FilenameUtils
от Apache Commons IO
.
Пример использования:
public static void main(String[] arguments) throws ZipException
{
Zipper zipper = new Zipper("password");
zipper.pack("encrypt-me.txt");
zipper.unpack("encrypt-me", "D:\\");
}
Ответ 4
Не существует Java API по умолчанию для создания защищенного паролем файла. Существует еще один пример того, как это сделать здесь.