在java中的密码保护的zip文件

我使用java创build了zip文件,如下所示

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

现在我想当我点击压缩文件,它应该提示我input密码,然后解压缩zip文件。 请任何帮助,我应该怎么走?

标准的Java API不支持密码保护的zip文件。 幸运的是,好人已经为我们实现了这样的能力。 请看看这篇解释如何创build密码保护的zip的文章: http : //java.sys-con.com/node/1258827

试试以下基于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:\\"); } 

下面的示例代码将zip和密码保护您的文件。 这个REST服务接受原始文件的字节。 它将字节数组和密码保护起来。 然后它发送密码保护的压缩文件的字节作为响应。 代码是向REST服务发送和接收二进制字节的示例,也是用密码保护压缩文件的示例。 字节从stream中压缩,所以没有文件存储在服务器上。

  • 在java中使用Jersey API使用JAX-RS API
  • 客户端正在使用Jersey-client API。
  • 使用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 testing:

 @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,但你可以使用Pader的HeaderParam,而不是从简单的视线隐藏密码。 相应地修改testing方法。

编辑2 – RESTpath是filezip / services / zip / bindata / protect / qparam

filezip是战争的名字。 服务是web.xml中的URL映射。 zip是类级别的path注释。 bindata / protect / qparam是方法级别的path注释。

没有默认的Java API来创build受密码保护的文件。 还有一个关于如何在这里做的例子。