Arquivo zip protegido por senha em java

Eu criei o arquivo zip usando java como abaixo do snippet

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); } } } 

Agora eu quero quando eu clicar no arquivo zip deve me pedir para digitar a senha e, em seguida, descomprimir o arquivo zip. Por favor, qualquer ajuda, como devo ir mais longe?

A API Java padrão não suporta arquivos zip protegidos por senha. Felizmente bons rapazes já implementaram essa habilidade para nós. Por favor, dê uma olhada neste artigo que explica como criar zip protegido por senha: http://java.sys-con.com/node/1258827

O código de exemplo abaixo irá compactar e proteger seu arquivo com senha. Este serviço REST aceita bytes do arquivo original. Ele fecha a matriz de bytes e a senha protege-a. Em seguida, ele envia bytes de arquivo compactado protegido por senha como resposta. O código é uma amostra de envio e recebimento de bytes binários para e de um serviço REST e também de compactação de um arquivo com proteção por senha. Os bytes são zipados do stream, portanto, nenhum arquivo é armazenado no servidor.

  • Usa API JAX-RS usando a API Jersey em java
  • O cliente está usando a API do cliente Jersey.
  • Usa biblioteca de código aberto zip4j 1.3.2 e 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; } 

Teste unitário abaixo:

 @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(); } } 

Sinta-se à vontade para usar e modificar. Por favor, deixe-me saber se você encontrar algum erro. Espero que isto ajude.

Editar 1 – Usando QueryParam, mas você pode usar HeaderParam para PUT em vez disso, para ocultar o passwd à vista. Modifique o método de teste de acordo.

Editar 2 – o caminho REST é filezip / services / zip / bindata / protect / qparam

filezip é o nome da guerra. services é o mapeamento de URL no web.xml. zip é uma anotação de caminho de nível de class. bindata / protect / qparam é a anotação do caminho de nível do método.

Tente o seguinte código que é baseado no 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 é do Apache Commons IO .

Exemplo de uso:

 public static void main(String[] arguments) throws ZipException { Zipper zipper = new Zipper("password"); zipper.pack("encrypt-me.txt"); zipper.unpack("encrypt-me", "D:\\"); } 

Não há API Java padrão para criar um arquivo protegido por senha. Há outro exemplo sobre como fazer isso aqui .